2011-06-04 91 views
2

我使用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),因为它位于标题栏下方。

+0

看来这可能是UIKit中的一个错误,不确定。我通过动画contentInset而不是frame.size.height找到了一个修复。你可以看到它在我的项目分叉https://github.com/webartisan/TPKeyboardAvoiding – 2011-06-09 23:48:50

回答

2

看来这可能是UIKit中的一个错误,不确定。我通过动画contentInset而不是frame.size.height找到了一个修复。你可以在我的项目中看到它http://github.com/wordofchristian/TPKeyboardAvoiding

+0

链接不工作! – Maulik 2011-12-10 09:07:45

+0

刚刚更新了它 – 2011-12-11 02:27:24

+0

它给出了没有UIKit和Foundation框架已经添加的文件或目录!任何猜测? – Maulik 2011-12-12 04:47:52