Reputation: 841
I am trying to set the contentOffset
of a tableView
when the keyboard
is presented. The actual code is inside a CustomTableView : UITableView <UIScrollViewDelegate>
, as it is used widely throughout the app, hence the use of self
as the tableView
.
My code looks like this:
- (void)keyboadDidAppear:(NSNotification *)notification {
NSTimeInterval animationDuration = [[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGRect keyboardBeginFrame = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
CGFloat keyboardHeight = CGRectGetHeight(keyboardBeginFrame);
CGPoint contentOffset = self.contentOffset;
originalContentOffset = self.contentOffset;//hold reference to reset it when keyboard is hidden
contentOffset.y += keyboardHeight;
[UIView animateWithDuration:animationDuration animations:^{
[self layoutIfNeeded];
} completion:^(BOOL finished) {
if (finished) {
[self setContentOffset:contentOffset animated:YES];
}
}];
}
The problem is that, it always offsets the content by the keyboard's height, which is wrong, when the user taps a tableCell
that is near the top of the tableView
.
Ideally, I would want to offset the content so the tapped tableCell
is just above the keyboard.
The problem is that I don't know how to do it. I have a rough idea that I would need something like:
distanceBetweenTappedCellAndTableBottom > keyboardHeight ? do nothing : offsetContentBy keyboardHeight + tappedCellHeight.
Any suggestions on how could I come up with the numbers? or is there a better solution?
Later edit:
I can't use the contentInset
as the tableView
has sectionHeaders
, and setting the contentInset
causes the sectionHeaders
to stay fixes, while the rows
move up.
Solution based on suggestions below:
CGSize kbSize = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
NSTimeInterval duration = [[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGFloat height = UIDeviceOrientationIsPortrait([[UIDevice currentDevice] orientation]) ? kbSize.width : kbSize.height;
height += 10.0;//it needs to be slightly higher so the textField is clearly visible.
originalEdgeInset = self.contentInset;
__weak typeof (self) block = self;
[UIView animateWithDuration:duration animations:^{
UIEdgeInsets edgeInsets = block.contentInset;
edgeInsets.bottom += height;
block.contentInset = edgeInsets;
edgeInsets = block.scrollIndicatorInsets;
edgeInsets.bottom += height;
block.scrollIndicatorInsets = edgeInsets;
}];
Upvotes: 2
Views: 1172
Reputation: 685
I think keyboard will not move when you add keyboard height into edgeInset as well
CGSize kbSize = [[[sender userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
NSTimeInterval duration = [[[sender userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGFloat height = UIDeviceOrientationIsPortrait([[UIDevice currentDevice] orientation]) ? kbSize.width : kbSize.height;
[UIView animateWithDuration:duration animations:^{
UIEdgeInsets edgeInsets = _generalTableView.contentInset;
edgeInsets.bottom += height;
_generalTableView.contentInset = edgeInsets;
edgeInsets = _generalTableView.scrollIndicatorInsets;
edgeInsets.bottom += height;
_generalTableView.scrollIndicatorInsets = edgeInsets;
}];
Upvotes: 3