10

我有一个带有静态单元格的表格视图。一个单元格包含 aUITextView并且heightForRowAtIndexPath:是动态计算的,因此单元格总是足够高以容纳文本(实际上,这部分在 iOS 7 下需要一些工作,因为不再可能简单地向 textView 询问它的contentSize)。

当我在文本视图中点击开始编辑时,键盘动画就位,tableView 上的 contentInsets 会自动调整以解决此问题(即,iPhone 纵向方向的底部插图为 216 像素),光标/插入符号变为可见,并且然后表格视图滚动到另一个位置。它最终看起来像一个反弹。

这是模拟器中的视频:https ://www.dropbox.com/s/htdbb0t7985u6n4/textview-bounce.mov

请注意,插入符号在键盘上方有一秒钟。我一直在记录表格视图contentOffset,我可以看到它滚动到一个不错的值,然后突然“转身”并向后滚动。

奇怪的是,如果我在模拟器中打开慢速动画,问题就会消失;contentOffset逆转没有发生,事情按我的预期工作(即 iOS 6 行为)。

这是动画慢的视频:https ://www.dropbox.com/s/nhn7vspx86t4exb/textview-nobounce.mov

实施说明:

  • 文本视图是粉红色的,并且具有 AutoLayout 约束,使其固定在距离为 0 的单元格上(左侧除外,即 10pts)
  • boundingRectWithSize:用来计算表格视图高度,调整 lineFragmentPadding 和任何顶部/底部插图。似乎工作。
  • 我已将 textView 设置为不可滚动,但当scrollEnabled== YES时没有发现任何不同
  • 这是一个表视图控制器,automaticallyAdjustsScrollViewInsets== YES
4

1 回答 1

3

尝试在键盘出现时调整 UITableView 框架。[self attachKeyboardHelper]在 viewWillAppear 和viewWillDisappear 中调用[self detachKeyboardHelper]

- (void)attachKeyboardHelper{
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillAppear:)
                                                 name:UIKeyboardWillShowNotification
                                               object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillHide:)
                                                 name:UIKeyboardWillHideNotification
                                               object:nil];
}

- (void)detachKeyboardHelper{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)keyboardWillAppear:(NSNotification *)notification{
    NSDictionary* userInfo = [notification userInfo];

    NSTimeInterval animationDuration;
    UIViewAnimationCurve animationCurve;
    CGRect keyboardEndFrame;

    [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
    [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
    [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardEndFrame];

    // Animate up or down
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:animationDuration];

    CGRect keyboardFrame = [self.view convertRect:keyboardEndFrame toView:nil];
    if(self.view==self.tableView){
        CGRect newTableFrame = CGRectMake(self.tableView.frame.origin.x, self.tableView.frame.origin.y, self.tableView.frame.size.width, self.view.bounds.size.height-keyboardFrame.size.height);
        self.tableView.frame = newTableFrame;
    }else{
        CGRect newTableFrame = CGRectMake(self.tableView.frame.origin.x, self.tableView.frame.origin.y, self.tableView.frame.size.width, self.view.bounds.size.height-self.tableView.frame.origin.y-keyboardFrame.size.height);
        self.tableView.frame = newTableFrame;
    }

    [UIView commitAnimations];
}

- (void)keyboardWillHide:(NSNotification *)notification{
    NSDictionary* userInfo = [notification userInfo];

    NSTimeInterval animationDuration;
    UIViewAnimationCurve animationCurve;
    CGRect keyboardEndFrame;

    [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
    [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
    [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardEndFrame];


    CGRect newTableFrame = CGRectMake(self.tableView.frame.origin.x, self.tableView.frame.origin.y, self.tableView.frame.size.width, self.view.superview.bounds.size.height-self.tableView.frame.origin.y);
    self.tableView.frame = newTableFrame;
    if(newTableFrame.size.height>self.tableView.contentSize.height-self.tableView.contentOffset.y){
        float newOffset=MAX(self.tableView.contentSize.height-newTableFrame.size.height, 0);
        [self.tableView setContentOffset:CGPointMake(0, newOffset) animated:YES];
    }

}
于 2013-12-11T04:16:32.920 回答