I have this code, which resizes the tableview when I click a textfield inside of a cell so that the keyboard doesn’t overlap the bottom row. The problem is, after it resizes, it scrolls to the top of the table instead of the cell that I had clicked the textfield in.
- (void)keyboardDidShow:(NSNotification *)notification
{
NSDictionary *userInfo = [notification userInfo];
CGSize size = [[userInfo objectForKey: UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
CGRect frame = CGRectMake(self.vitalsTableView.frame.origin.x,
self.vitalsTableView.frame.origin.y,
self.vitalsTableView.frame.size.width,
self.vitalsTableView.frame.size.height - size.height);
self.vitalsTableView.frame = frame;
VitalsTableViewCell *cell = (VitalsTableViewCell*)[self.selectedTextField superview];
[self.vitalsTableView scrollRectToVisible:cell.frame animated:YES];
}
- (void)keyboardWillHide:(NSNotification *)notification
{
NSDictionary *userInfo = [notification userInfo];
CGSize size = [[userInfo objectForKey: UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
self.vitalsTableView.frame = CGRectMake(self.vitalsTableView.frame.origin.x,
self.vitalsTableView.frame.origin.y,
self.vitalsTableView.frame.size.width,
self.vitalsTableView.frame.size.height + size.height);
}
- (void) textFieldDidBeginEditing:(UITextField *)textField {
self.selectedTextField = textField;
// [self scrollToRectOfTextField];
NSIndexPath *path = [self.vitalsTableView indexPathForSelectedRow];
[self.vitalsTableView scrollToRowAtIndexPath:path atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
- (void)scrollToRectOfTextField {
VitalsTableViewCell *cell = (VitalsTableViewCell*)[self.selectedTextField superview];
CGRect r = CGRectMake(self.selectedTextField.frame.origin.x,
cell.frame.origin.y+self.selectedTextField.frame.origin.y,
self.selectedTextField.frame.size.width,
self.selectedTextField.frame.size.height);
[self.vitalsTableView scrollRectToVisible:r animated:YES];
NSIndexPath *path = [self.vitalsTableView indexPathForSelectedRow];
[self.vitalsTableView scrollToRowAtIndexPath:path atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
When you change the frame of the tableview, it calls all the necessary methods to redraw it and resets the
contentOffsetof the tableview to the default, which is at the top. Every time you change the frame, you will have to scroll to theCGPointorCGRectyou desire. So first save the point where you want to scroll, then resize the frame, then scroll to the point’s location relative to the new frame.I see in your code that you are scrolling, but it is to the wrong rect,
First of all, I’d take out the last two lines about scrolling to a row at index path. Second, if you’d examine
r.originyou’d probably get a point at (0, 0) because the origin of the text field’s frame is relative to its superview, not to the tableview. You can figure out where the text field’s frame is relative to the table view by using theconvertRect:toView:method which is documented here and also described here.