我使用TPKeyboardAvoidingScrollView在这里找到:https://github.com/michaeltyson/TPKeyboardAvoiding滚动型的位置跳跃时contentOffset具有价值
下面是从该类相关的代码块:
- (void)keyboardWillShow:(NSNotification*)notification {
if (!CGRectEqualToRect(priorFrame, CGRectZero)) return;
UIView *firstResponder = [self findFirstResponderBeneathView:self];
if (!firstResponder) {
// No child view is the first responder - nothing to do here
return;
}
priorFrame = self.frame;
// Use this view's coordinate system
CGRect keyboardBounds = [self convertRect:[[[notification userInfo] objectForKey:_UIKeyboardFrameEndUserInfoKey] CGRectValue] fromView:nil];
CGRect screenBounds = [self convertRect:[UIScreen mainScreen].bounds fromView:nil];
if (keyboardBounds.origin.y == 0) keyboardBounds.origin = CGPointMake(0, screenBounds.size.height - keyboardBounds.size.height);
CGFloat spaceAboveKeyboard = keyboardBounds.origin.y - self.bounds.origin.y;
CGFloat offset = -1;
CGRect newFrame = self.frame;
newFrame.size.height -= keyboardBounds.size.height -
((keyboardBounds.origin.y+keyboardBounds.size.height)
- (self.bounds.origin.y+self.bounds.size.height));
CGRect firstResponderFrame = [firstResponder convertRect:firstResponder.bounds toView:self];
if (firstResponderFrame.origin.y + firstResponderFrame.size.height >= screenBounds.origin.y + screenBounds.size.height - keyboardBounds.size.height) {
// Prepare to scroll to make sure the view is above the keyboard
offset = firstResponderFrame.origin.y + self.contentOffset.y;
if (self.contentSize.height - offset < newFrame.size.height) {
// Scroll to the bottom
offset = self.contentSize.height - newFrame.size.height;
} else {
if (firstResponder.bounds.size.height < spaceAboveKeyboard) {
// Center vertically if there's room
offset -= floor((spaceAboveKeyboard-firstResponder.bounds.size.height)/2.0);
}
if (offset + newFrame.size.height > self.contentSize.height) {
// Clamp to content size
offset = self.contentSize.height - newFrame.size.height;
}
}
}
// Shrink view's height by the keyboard's height, and scroll to show the text field/view being edited
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
[UIView setAnimationDuration:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue]];
self.frame = newFrame;
if (offset != -1) {
[self setContentOffset:CGPointMake(self.contentOffset.x, offset) animated:YES];
}
[UIView commitAnimations];
}
- (void)keyboardWillHide:(NSNotification*)notification {
if (CGRectEqualToRect(priorFrame, CGRectZero)) return;
// Restore dimensions to prior size
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
[UIView setAnimationDuration:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue]];
self.frame = priorFrame;
priorFrame = CGRectZero;
[UIView commitAnimations];
}
我有一个问题,当键盘开始隐藏时,scrollView会立即跳起来,所以它的原点位于窗口顶部之上。然后,它进入适当的位置。
我发现这只发生在动画运行时contentOffset> 0的情况下。
在调试过程中,我注意到当键盘解除动画开始时,内容偏移量为54。 我发现,如果我加入这个代码keyboardWillHide的开头:
priorFrame.size.height -= self.contentOffset;
...那么不会发生任何跳和动画会正常运行,但滚动视图将在年底太短。
任何想法?
另请注意,我的scrollView的正常框架是(0,44,320,416),因为它位于标题栏下方。
看来这可能是UIKit中的一个错误,不确定。我通过动画contentInset而不是frame.size.height找到了一个修复。你可以看到它在我的项目分叉https://github.com/webartisan/TPKeyboardAvoiding – 2011-06-09 23:48:50