iPhone:将表格视图单元格滚动到自定义键盘对齐工具栏上方可见的位置?

iPhone:将表格视图单元格滚动到自定义键盘对齐工具栏上方可见的位置?,iphone,objective-c,uitableview,user-interface,scroll,Iphone,Objective C,Uitableview,User Interface,Scroll,在过去的几天里,我一直在问一两个问题,我正在开发一个应用程序,使自定义工具栏与iPhone键盘顶部对齐。我正在使用Josh在中描述的方法;基本上,我让视图控制器监听UIKeyboardWillShowNotification,并根据需要添加工具栏 视图控制器本身管理一个表视图,该表视图的所有单元格都包含一个UITextField。显示的键盘和工具栏正在编辑这些文本字段。我现在唯一的问题是:当键盘和工具栏显示在表格一半以上的单元格上时,它会滚动到键盘上方可见,但不会显示在工具栏上方 单元格和文本字

在过去的几天里,我一直在问一两个问题,我正在开发一个应用程序,使自定义工具栏与iPhone键盘顶部对齐。我正在使用Josh在中描述的方法;基本上,我让视图控制器监听UIKeyboardWillShowNotification,并根据需要添加工具栏

视图控制器本身管理一个表视图,该表视图的所有单元格都包含一个UITextField。显示的键盘和工具栏正在编辑这些文本字段。我现在唯一的问题是:当键盘和工具栏显示在表格一半以上的单元格上时,它会滚动到键盘上方可见,但不会显示在工具栏上方

单元格和文本字段仍可编辑,但大约一半的单元格隐藏在工具栏下。如果我消失工具栏(不要将其添加到通知响应程序中),整个单元格将可见,但很明显,我将失去工具栏提供的功能

有没有办法更改文本字段滚动到的位置?我尝试过使用UITableView方法
scrollToRowAtIndexPath:atScrollPosition:animated:
,但在几个单元格之间切换时,它往往会产生奇怪的结果


将表格视图单元格滚动到自定义键盘工具栏上方可见位置的最佳方法是什么?

也许您可以将
UITableView
调整为导航栏和键盘上方工具栏之间的高度,然后将行滚动到视图中?

我完全按照您在我的应用程序中所描述的操作。这是我使用的代码,一字不差。这是非常好的动画,似乎工作得很好

两项免责声明:

  • 作为自定义初始化的一部分传入parentView
  • 我没有写这段代码,我不会因此而受到赞扬。我是从马特·加拉赫的博客上得到的

  • 静态常量CGFloat键盘\u动画\u持续时间=0.3;
    静态常数CGFloat最小滚动分数=0.2;
    静态常数CGFloat最大滚动分数=0.8;
    //调整以下值以考虑工具栏的高度
    静态常数CGFloat纵向键盘高度=216;
    -(void)textfielddidediting:(UITextField*)textField
    {
    CGRect viewFrame=self.parentView.frame;
    viewFrame.origin.y+=动画距离;
    [UIView beginAnimations:nil上下文:NULL];
    [UIView setAnimationBeginsFromCurrentState:是];
    [UIView设置动画持续时间:键盘动画持续时间];
    [self.parentView setFrame:viewFrame];
    [UIView委员会];
    }
    -(无效)textFieldDidBeginEditing:(UITextField*)textField{
    CGRect textFieldRect=[self.parentView.window convertRect:textField.bounds fromView:textField];
    CGRect viewRect=[self.parentView.window convertRect:self.parentView.bounds fromView:self.parentView];
    CGFloat midline=textFieldRect.origin.y+0.5*textFieldRect.size.height;
    CGFloat分子=中线-viewRect.origin.y-最小滚动分数*viewRect.size.height;
    CGFloat分母=(最大滚动分数-最小滚动分数)*viewRect.size.height;
    CGFloat heightFraction=分子/分母;
    如果(高度分数<0.0){
    高度分数=0.0;
    }否则如果(高度分数>1.0){
    高度分数=1.0;
    }
    动画距离=地板(纵向\键盘\高度*高度分数);
    CGRect viewFrame=self.parentView.frame;
    viewFrame.origin.y-=动画距离;
    [UIView beginAnimations:nil上下文:NULL];
    [UIView setAnimationBeginsFromCurrentState:是];
    [UIView设置动画持续时间:键盘动画持续时间];
    [self.parentView setFrame:viewFrame];
    [UIView委员会];
    }
    
    由于所有的
    UITableView
    s也都是
    UIScrollView
    s,因此您可以调用它们上的所有标准滚动方法

    这样做可以:

    - (void)scrollTableView:(UITableView *)tableView toIndexPath:(NSIndexPath *)indexPath withBottomPadding:(CGFloat)bottomPadding
    {
        CGRect rectForRow = [tableView rectForRowAtIndexPath:indexPath];
        CGRect bounds = [tableView bounds];
        CGPoint contentOffset = [tableView contentSize];
        if (rectForRow.origin.y + rectForRow.size.height > contentOffset.y + bounds.size.height - bottomPadding)
            [tableView setContentOffset:rectForRow.origin.y + rectForRow.size.height - bounds.size.height - bottomPadding animated:YES];
        else
            [tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionNone animated:YES];
    }
    

    注意:我现在不在使用Xcode的Mac上。我将在测试此代码时

    假设您知道将在键盘上方显示的nsindepath,您可以使用以下快速而干净的方法:

    - (void)textFieldDidBeginEditing:(UITextField *)textField {
        UITableViewCell *aCell = [myTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:6 inSection:0]];
        CGSize cellSize = aCell.frame.size;
        [myTableView setContentOffset:CGPointMake(0, cellSize.height*6) animated:YES];
    }       
    
    - (void)textFieldDidEndEditing:(UITextField *)textField {
        [myTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] 
                           atScrollPosition:UITableViewScrollPositionTop 
                                   animated:YES];
    }
    
    由于UITableView继承自UIScrollView,因此可以调整contentOffset属性以反映感兴趣的行可见性


    DidEndEditing方法中,必须恢复原始滚动位置。这是通过一个标准的ScrollToRowatineXpath:atScrollPosition:animated调用实现的。

    我尝试了一下-表视图的大小似乎可以调整,如果你试图将一个单元格的大小调整到屏幕上,那么它就会被严重阻塞。我假设你是在-我也看到过它,它实际上不处理UITableView,只处理带有UITextFields的静态视图。这种方法的问题是,当用户在表视图中滚动时,动画距离可能会发生变化。我在UITableView中使用它,没有任何问题。我实现了这一点,但在仔细检查代码和结果后,它所做的只是将表视图的原点从屏幕上移走。它具有博客文章中描述的效果,但在编辑靠近表格底部的单元格时,用户无法看到顶部的几个表格视图单元格。我想我当时不理解这个问题。只有这么多的屏幕空间。我不确定如何在顶部显示单元格,在底部编辑单元格,以及显示键盘。也许我实现了一些稍微偏离的功能-在初始值设定项中为parentView传递了什么视图?我使用self.tableView代替parentView,但这可能会弄乱它。
    - (void)textFieldDidBeginEditing:(UITextField *)textField {
        UITableViewCell *aCell = [myTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:6 inSection:0]];
        CGSize cellSize = aCell.frame.size;
        [myTableView setContentOffset:CGPointMake(0, cellSize.height*6) animated:YES];
    }       
    
    - (void)textFieldDidEndEditing:(UITextField *)textField {
        [myTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] 
                           atScrollPosition:UITableViewScrollPositionTop 
                                   animated:YES];
    }