2014-10-04 58 views
0

相关的新手问题:我的textView中输入的文本位于textview区域的顶部,直到文本进入第二行,此时它跳转到键盘上方的行,然后向上滚动以添加新行。但我希望文本保持在文本视图的顶部,直到文本到达键盘上方的行,然后向上滚动。我无法弄清楚如何解决这个问题。XCODE 5+ ...如何在TextView中停止添加第二行时跳转到键盘上方的文本?

我花了一些时间搜索,没有找到一个简单的例子。任何建议表示赞赏。

+0

我希望我能... – PatriciaW 2014-10-05 03:00:56

+0

有一件事我很确定是constraintToAdjust - 目前它被设置为垂直 - 底部布局指南 - 文本视图 – PatriciaW 2014-10-05 15:40:44

回答

0

最后,我下载了Apple Keyboard Accessory应用程序,并将我的代码更改为匹配,现在它可以正常工作。 这里是工作的代码 - 但它并不意味着是优雅的代码的例子,因为我是一个业余的:

#import "CREWGenericNotesVC.h" 

@interface CREWGenericNotesVC() 

@property (nonatomic, weak) IBOutlet UIBarButtonItem *doneButton; 
@property (nonatomic, weak) IBOutlet UITextView *textView; 
// the height constraint we want to change when the keyboard shows/hides 
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *constraintToAdjust; 

// @property(nonatomic) CGSize contentSize; 

@end 

@implementation CREWGenericNotesVC 

#define VIEW_NAME @"CREWGenericNotesVC" // need the name of the view that calls this 
#define VIEW_DESCRIPTION @"Generic notes" 
#define RETURN_NC @"NCEmergencyKitsList" // where to return to when complete processing 

- (void)viewDidLoad { 

[super viewDidLoad]; 

// [_textView addObserver:self forKeyPath:@"contentSize" options: (NSKeyValueObservingOptionNew) context:NULL]; 

// load saved notes into textView 

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 


self.navigationItem.title = [defaults objectForKey:@"VCtitle"]; 
self.navigationItem.rightBarButtonItem = self.doneButton; 

[self initializeView]; 

} 

// create and load entity and notes 
- (void) initializeView 
{ 
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 

NSString *viewName = [defaults objectForKey:@"VCname"]; // parameter to specify which view is calling notes and 
CREWAppDelegate *appDelegate = [[UIApplication sharedApplication]delegate]; 
NSManagedObjectContext *context = [appDelegate managedObjectContext]; 

NSEntityDescription *entityDesc = [NSEntityDescription entityForName:@"Notes" inManagedObjectContext:context]; 

NSFetchRequest * request = [[NSFetchRequest alloc] init]; 
[request setEntity:entityDesc]; 

NSPredicate *pred = [NSPredicate predicateWithFormat:@"(viewName = %@)", VIEW_NAME]; 
[request setPredicate:pred]; 

NSError *error = nil; 
NSArray * objects = [context executeFetchRequest:request error:&error]; 

if ([objects count] == 0) { // create new notes instance if not already created 
    [self newNotes:viewName]; // create a new empty note object 
} else { 
    self.textView.text = [self getNotes:viewName]; // load existing notes 
} 
} // end of initializeView 

// create a new empty Notes record 
- (void) newNotes:(NSString*)viewName 
{ 
NSError *error = nil; 
CREWAppDelegate *appDelegate = [[UIApplication sharedApplication]delegate]; 
NSManagedObjectContext *context = [appDelegate managedObjectContext]; 

NSManagedObject * newNotes; 

newNotes = [NSEntityDescription insertNewObjectForEntityForName:@"Notes" inManagedObjectContext:context]; 

[newNotes setValue:viewName forKey:@"viewName"]; 
[newNotes setValue:nil forKey:@"viewNotes"]; 

if (! [context save:&error]) 
    NSLog(@"newNotes Couldn't save new data! Error:%@", [error description]); 
} // end of newNotes 

// read existing notes 
- (NSString*) getNotes:(NSString*)viewName// get stored notes 
{ 
CREWAppDelegate *appDelegate = [[UIApplication sharedApplication]delegate]; 
NSManagedObjectContext *context = [appDelegate managedObjectContext]; 

NSEntityDescription *entityDesc = [NSEntityDescription entityForName:@"Notes" inManagedObjectContext:context]; 

NSFetchRequest * request = [[NSFetchRequest alloc] init]; 
[request setEntity:entityDesc]; 

NSPredicate *pred = [NSPredicate predicateWithFormat:@"(viewName = %@)", viewName]; 
[request setPredicate:pred]; 

// Execute Fetch Request 
NSManagedObjectContext * matches = nil; 
NSError *fetchError = nil; 
NSArray *objects = [appDelegate.managedObjectContext executeFetchRequest:request error:&fetchError]; 
if (fetchError) { 
    NSLog(@"getNotes Fetch error:%@", fetchError); 
}; 

NSString *viewNotes; 

if (! [objects count] == 0) { 
    matches = objects [0]; 
    viewNotes = [matches valueForKey : @"viewNotes"]; 
} 
return viewNotes; 
} // end of getNotes 

- (void)saveNotes:(NSString*)viewName toValue:(NSString*)newNotes // to get stored notes and update them 
{ 
CREWAppDelegate *appDelegate = [[UIApplication sharedApplication]delegate]; 
NSManagedObjectContext *context = [appDelegate managedObjectContext]; 

NSEntityDescription *entityDesc = [NSEntityDescription entityForName:@"Notes" inManagedObjectContext:context]; // get notes entity 

NSFetchRequest * request = [[NSFetchRequest alloc] init]; 
[request setEntity:entityDesc]; 

NSPredicate *pred = [NSPredicate predicateWithFormat:@"(viewName = %@)", viewName ]; 
[request setPredicate:pred]; 

NSManagedObject *matches = nil; 
NSError *error = nil; 
NSArray * objects = [context executeFetchRequest:request error:&error]; 

if (![objects count] == 0) { 
    matches = objects[0]; 
} 
[matches setValue:newNotes forKey:@"viewNotes"]; 

if (! [context save:&error]) NSLog(@"newNotes Couldn't save notes! Error:%@", [error description]); 
} // end of saveSwitch 

// keyboard stuff 

- (void)viewDidAppear:(BOOL)animated { 

// observe keyboard hide and show notifications to resize the text view appropriately 
[[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(keyboardWillShow:) 
              name:UIKeyboardWillShowNotification 
              object:nil]; 
[[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(keyboardWillHide:) 
              name:UIKeyboardWillHideNotification 
              object:nil]; 

// start editing the UITextView (makes the keyboard appear when the application launches) 
[self editAction:self]; 
} 

- (void)viewDidDisappear:(BOOL)animated { 

[[NSNotificationCenter defaultCenter] removeObserver:self 
               name:UIKeyboardWillChangeFrameNotification 
               object:nil]; 
[[NSNotificationCenter defaultCenter] removeObserver:self 
               name:UIKeyboardWillHideNotification 
               object:nil]; 
} 

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { 
[self adjustSelection:self.textView]; 
} 

#pragma mark - Actions 

- (IBAction)doneAction:(id)sender { 

// user tapped the Done button, release first responder on the text view 
[self.textView resignFirstResponder]; 

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 

NSString *viewName = [defaults objectForKey:@"VCname"]; // parameter to specify where to save notes 
// NSString *stringNC = [defaults objectForKey:@"NCname"]; // parameter to specify which navigation controller to return to 
[self saveNotes:viewName toValue: self.textView.text]; // save notes 

[defaults stringForKey:@"NCname"]; 
UIViewController *viewController = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:[defaults stringForKey:@"NCname"]]; 
[self presentViewController:viewController animated:YES completion:nil]; 
} 

- (IBAction)editAction:(id)sender { 

// user tapped the Edit button, make the text view first responder 
[self.textView becomeFirstResponder]; 
} 

#pragma mark - UITextViewDelegate 

- (BOOL)textViewShouldBeginEditing:(UITextView *)aTextView { 
} 

self.navigationItem.rightBarButtonItem = self.doneButton; 

return YES; 
} 

- (BOOL)textViewShouldEndEditing:(UITextView *)aTextView { 

[aTextView resignFirstResponder]; 

return YES; 
} 

- (void)adjustSelection:(UITextView *)textView { 

// workaround to UITextView bug, text at the very bottom is slightly cropped by the keyboard 
if ([textView respondsToSelector:@selector(textContainerInset)]) { 
    [textView layoutIfNeeded]; 
    CGRect caretRect = [textView caretRectForPosition:textView.selectedTextRange.end]; 
    caretRect.size.height += textView.textContainerInset.bottom; 
    [textView scrollRectToVisible:caretRect animated:NO]; 
} 
} 

- (void)textViewDidBeginEditing:(UITextView *)textView { 

[self adjustSelection:textView]; 
} 

- (void)textViewDidChangeSelection:(UITextView *)textView { 

[self adjustSelection:textView]; 
} 


#pragma mark - Responding to keyboard events 

- (void)adjustTextViewByKeyboardState:(BOOL)showKeyboard keyboardInfo:(NSDictionary *)info { 

/* 
Reduce the size of the text view so that it's not obscured by the keyboard. 
Animate the resize so that it's in sync with the appearance of the keyboard. 
*/ 

// transform the UIViewAnimationCurve to a UIViewAnimationOptions mask 
UIViewAnimationCurve animationCurve = [info[UIKeyboardAnimationCurveUserInfoKey] unsignedIntegerValue]; 
UIViewAnimationOptions animationOptions = UIViewAnimationOptionBeginFromCurrentState; 
if (animationCurve == UIViewAnimationCurveEaseIn) { 
    animationOptions |= UIViewAnimationOptionCurveEaseIn; 
} 
else if (animationCurve == UIViewAnimationCurveEaseInOut) { 
    animationOptions |= UIViewAnimationOptionCurveEaseInOut; 
} 
else if (animationCurve == UIViewAnimationCurveEaseOut) { 
    animationOptions |= UIViewAnimationOptionCurveEaseOut; 
} 
else if (animationCurve == UIViewAnimationCurveLinear) { 
    animationOptions |= UIViewAnimationOptionCurveLinear; 
} 

[self.textView setNeedsUpdateConstraints]; 

if (showKeyboard) { 
    UIDeviceOrientation orientation = self.interfaceOrientation; 
    BOOL isPortrait = UIDeviceOrientationIsPortrait(orientation); 

    NSValue *keyboardFrameVal = [info objectForKey:UIKeyboardFrameEndUserInfoKey]; 
    CGRect keyboardFrame = [keyboardFrameVal CGRectValue]; 
    CGFloat height = isPortrait ? keyboardFrame.size.height : keyboardFrame.size.width; 

    // adjust the constraint constant to include the keyboard's height 
    self.constraintToAdjust.constant += height; 
} 
else { 
    self.constraintToAdjust.constant = 0; 
} 

NSTimeInterval animationDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]; 

[UIView animateWithDuration:animationDuration delay:0 options:animationOptions animations:^{ 
    [self.view layoutIfNeeded]; 
} completion:nil]; 

// now that the frame has changed, move to the selection or point of edit 
NSRange selectedRange = self.textView.selectedRange; 
[self.textView scrollRangeToVisible:selectedRange]; 
} 

- (void)keyboardWillShow:(NSNotification *)notification { 

/* 
Reduce the size of the text view so that it's not obscured by the keyboard. 
Animate the resize so that it's in sync with the appearance of the keyboard. 
*/ 

NSDictionary *userInfo = [notification userInfo]; 
[self adjustTextViewByKeyboardState:YES keyboardInfo:userInfo]; 
} 

- (void)keyboardWillHide:(NSNotification *)notification { 

/* 
Restore the size of the text view (fill self's view). 
Animate the resize so that it's in sync with the disappearance of the keyboard. 
*/ 

NSDictionary *userInfo = [notification userInfo]; 
[self adjustTextViewByKeyboardState:NO keyboardInfo:userInfo]; 
} 

@end 
+0

您能剥离与此问题没有直接关系的问题吗? – Braains 2015-09-29 19:35:25

+0

这个问题已发布近一年前。从那时起我已经将应用程序转换为使用Swift。 – PatriciaW 2015-09-30 20:02:16

相关问题