I have a UIViewCOntroller
that contains a UITextView
. When the keyboard appears I resize it like this:
#pragma mark - Responding to
For those that have a UITextView
inside a UIScrollView
where iOS < 7 took care of scrolling the caret into view: Here's how it works with iOS 7 (and also 5 & 6).
// This is the scroll view reference
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
// Track the current UITextView
@property (weak, nonatomic) UITextView *activeField;
- (void)textViewDidBeginEditing:(UITextView *)textView
{
self.activeField = textView;
}
- (void)textViewdDidEndEditing:(UITextView *)textView
{
self.activeField = nil;
}
// Setup the keyboard observers that take care of the insets & initial scrolling
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillBeHidden:)
name:UIKeyboardWillHideNotification object:nil];
- (void)keyboardWasShown:(NSNotification*)aNotification
{
// Set the insets above the keyboard
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
UIEdgeInsets insets = self.vForm.contentInset;
insets.bottom += kbSize.height;
self.vForm.contentInset = insets;
insets = self.vForm.scrollIndicatorInsets;
insets.bottom += kbSize.height;
self.vForm.scrollIndicatorInsets = insets;
// Scroll the active text field into view
CGRect aRect = self.vForm.frame;
aRect.size.height -= kbSize.height;
CGPoint scrollPoint = CGPointMake(0.0, self.activeField.frame.origin.y);
[self.scrollView setContentOffset:scrollPoint animated:YES];
}
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
self.vForm.contentInset = contentInsets;
self.vForm.scrollIndicatorInsets = contentInsets;
}
// This is where the magic happens. Set the class with this method as the UITextView's delegate.
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
// Scroll the textview to the caret position
[textView scrollRangeToVisible:textView.selectedRange];
// Scroll the scrollview to the caret position within the textview
CGRect targetRect = [textView caretRectForPosition:textView.selectedTextRange.end];
targetRect.origin.y += self.activeField.frame.origin.y;
[self.scrollView scrollRectToVisible:targetRect animated:YES];
return YES;
}
I tried to include most of the required glue code. The only things missing are setting the UITextView's delegate and dismissing the keyboard.
Took 2-3 days to figure out what previously worked. Thanks, Apple.