I have a UIScrollView
which has several dynamic views inside of it, each of which has a text field. When I begin typing in one of the boxes, I want the scroll view to scroll so that the field is at the top of the screen (visible above the keyboard). It works great; here is the code:
(void)didStartTyping:(id)sender {
[scrollView setContentOffset:CGPointMake(0, subView.frame.origin.y) animated:YES];
scrollView.scrollEnabled = NO;
}
(void)didFinishTyping:(id)sender {
scrollView.scrollEnabled = YES;
}
But, whenever the scroll view is scrolled up to the very top and I begin typing in the lowest visible text field, it doesn't scroll down far enough (short by about 40 px). The puzzling thing is that it works if I scroll down just one pixel from the top of the scroll view, but when I scroll up to the top it behaves very differently.
The best way i have managed to do this is to grab the keyboard frame, then update my scrollview insets when a text view gets textViewDidBeginEditing: called. Here im using a tableview, but the same logic should apply to a scrollview, the main difference being how you scroll. I use scrollToRowAtIndexPath, you will want to use scrollRectToVisible
//setup keyboard callbacks
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillHideNotification
object:nil];
}
- (void)keyboardWillShow:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
kbFrame = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
}
//this is called from your UITextViewDelegate when textViewDidBeginEditing: is called
- (void)updateActiveTextScroll:(UITextView*)textView
{
activeTextView = textView;
UIEdgeInsets inset;
UIInterfaceOrientation orient = [[UIApplication sharedApplication] statusBarOrientation];
if( UIInterfaceOrientationIsLandscape(orient) )
{
inset = UIEdgeInsetsMake(0.0, 0.0, kbFrame.size.width, 0.0);
}
else
{
inset = UIEdgeInsetsMake(0.0, 0.0, kbFrame.size.height, 0.0);
}
myTableView.contentInset = inset;
myTableView.scrollIndicatorInsets = inset;
[myTableView scrollToRowAtIndexPath:activeNSIndexPath
atScrollPosition:UITableViewScrollPositionBottom
animated:YES];
}
//dont forget to reset when the keyboard goes away
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
UIEdgeInsets inset = UIEdgeInsetsZero;
myTableView.contentInset = inset;
myTableView.scrollIndicatorInsets = inset;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With