首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >UITableViewCell平滑自动调整大小中的UITextView在iPad上显示和隐藏键盘,但在iPhone上有效

UITableViewCell平滑自动调整大小中的UITextView在iPad上显示和隐藏键盘,但在iPhone上有效
EN

Stack Overflow用户
提问于 2010-10-25 22:31:20
回答 2查看 13.8K关注 0票数 17

我已经实现了一个自定义的UITableViewCell,它包含一个可以随着用户输入自动调整大小的UITextView,类似于Contacts应用程序中的"Notes“字段。它在我的iPhone上工作正常,但当我在iPad中测试它时,我得到了一些非常奇怪的行为:当您到达一行的末尾时,键盘隐藏了一毫秒,然后立即再次显示。我会把它写成一个奇怪的bug,但它实际上会导致一些数据丢失,因为如果你在打字,它会丢失一两个字符。下面是我的代码:

《守则》

代码语言:javascript
复制
// returns the proper height/size for the UITextView based on the string it contains.
// If no string, it assumes a space so that it will always have one line.
- (CGSize)textViewSize:(UITextView*)textView {
     float fudgeFactor = 16.0;
     CGSize tallerSize = CGSizeMake(textView.frame.size.width-fudgeFactor, kMaxFieldHeight);
     NSString *testString = @" ";
     if ([textView.text length] > 0) {
          testString = textView.text;
     }
     CGSize stringSize = [testString sizeWithFont:textView.font constrainedToSize:tallerSize lineBreakMode:UILineBreakModeWordWrap];
     return stringSize;
}

// based on the proper text view size, sets the UITextView's frame
- (void) setTextViewSize:(UITextView*)textView {
     CGSize stringSize = [self textViewSize:textView];
     if (stringSize.height != textView.frame.size.height) {
          [textView setFrame:CGRectMake(textView.frame.origin.x,
                                        textView.frame.origin.y,
                                        textView.frame.size.width,
                                        stringSize.height+10)];  // +10 to allow for the space above the text itself 
     }
}

// as per: https://stackoverflow.com/questions/3749746/uitextview-in-a-uitableviewcell-smooth-auto-resize
- (void)textViewDidChange:(UITextView *)textView {

     [self setTextViewSize:textView]; // set proper text view size
     UIView *contentView = textView.superview;
     // (1) the padding above and below the UITextView should each be 6px, so UITextView's
     // height + 12 should equal the height of the UITableViewCell
     // (2) if they are not equal, then update the height of the UITableViewCell
     if ((textView.frame.size.height + 12.0f) != contentView.frame.size.height) {
         [myTableView beginUpdates];
         [myTableView endUpdates];

         [contentView setFrame:CGRectMake(0,
                                          0,
                                          contentView.frame.size.width,
                                          (textView.frame.size.height+12.0f))];
     }
}

- (CGFloat)tableView:(UITableView  *)tableView heightForRowAtIndexPath:(NSIndexPath  *)indexPath {
     int height;
     UITextView *textView = myTextView;
     [self setTextViewSize:textView];
     height = textView.frame.size.height + 12;
     if (height < 44) { // minimum height of 44
          height = 44;
          [textView setFrame:CGRectMake(textView.frame.origin.x,
                                        textView.frame.origin.y,
                                        textView.frame.size.width,
                                        44-12)];
      }
      return (CGFloat)height;
}

问题

所以,这是正在发生的事情

  1. 这段代码在我的iPhone和iPhone模拟器上都能100%正常工作。当我输入文本时,UITextView会平滑地增长,UITableViewCell也随之增长。然而,在iPad模拟器上,
  2. 变得扭曲了。当你在第一行输入时,它工作得很好,但当你到了一行的末尾,键盘会消失,然后立即重新出现,所以如果用户继续输入,应用程序会遗漏一两个字符。
  3. 这里有一些关于我注意到的奇怪行为的附加说明,这可能有助于解释它:
    • 另外,我发现在函数textViewDidChange:(UITextView *)textView中删除行[myTableView beginUpdates]; [myTableView endUpdates];会使UITextView正常增长,也不会显示和隐藏键盘,但不幸的是,然后,在these instructions之后,UITableViewCell不会增长到正确的height.
    • UPDATE:,我现在可以停止文本的奇怪移动;但键盘仍然隐藏和显示,这是非常strange.

有没有人知道如何让键盘持续显示,而不是在到达iPad的行尾时隐藏和显示?

附言:我对使用ThreeTwenty不感兴趣。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-10-30 04:56:55

您应该在以下位置返回NO:

代码语言:javascript
复制
 -(BOOL) textViewShouldEndEditing:(UITextView *)textView

如果您想要始终显示键盘。您应该通过将YES返回给这个委托函数来处理键盘应该隐藏的情况。

编辑:

我深入研究了一下,当tableView endUpdates调用时,它基本上做了3件事:

  1. 在tableView
  2. Updates单元格上禁用用户交互更改
  3. 在tableView

上启用用户交互

SDK(Platforms)之间的区别在于UIView setUserInteractionEnabled方法。由于UITableView不覆盖setUserInteractionEnabled方法,因此它是从超级(UIView)调用的。

当调用setUserInteractionEnabled时,iPhone查找私有字段_shouldResignFirstResponderWithInteractionDisabled,该字段默认返回NO,因此不会放弃第一个响应者(UITextView)

但在iPad上没有这样的检查AFAIK,所以它在step 1上辞去了UITextView,并在step 3上设置了焦点并使其成为第一响应者

基本上,textViewShouldEndEditing是你唯一的选择,根据SDK的文档,它可以让你保持专注。

当文本视图被要求放弃第一响应者状态时,调用此方法。当用户尝试将编辑焦点更改到另一个控件时,可能会发生这种情况。但是,在焦点实际更改之前,文本视图将调用此方法,以便让您的委托有机会决定是否应该这样做。

票数 15
EN

Stack Overflow用户

发布于 2011-01-30 20:18:56

我在一个iPad应用程序上也遇到了同样的问题,在没有计算文本高度的情况下,我想出了另一个解决方案。

首先,在IB中创建自定义UITableViewCell,并将UITextField放在单元格的contentView中。将文本视图的scrollEnabled设置为NO,将autoresizingMask设置为flexibleWidth和flexibleHeight,这一点很重要。

在ViewController中实现文本视图的委托方法-textViewDidChanged:,如下所示,其中-tableViewNeedsToUpdateHeight是一个类型为的实例变量,textHeight是一个我们将在下一步中定义的自定义方法。

代码语言:javascript
复制
- (void)textViewDidChange:(UITextView *)textView
{
    CGFloat newTextHeight = [textView contentSize].height;

    if (newTextHeight != textHeight)
    {
        textHeight = newTextHeight;
        [self tableViewNeedsToUpdateHeight];
    }
}

-tableViewNeedsToUpdateHeight方法调用表视图的beginUpdates-tableView:heightForRowAtIndexPath:委托方法,因此表视图本身将调用endUpdates方法。

代码语言:javascript
复制
- (void)tableViewNeedsToUpdateHeight
{
    BOOL animationsEnabled = [UIView areAnimationsEnabled];
    [UIView setAnimationsEnabled:NO];
    [table beginUpdates];
    [table endUpdates];
    [UIView setAnimationsEnabled:animationsEnabled];
}

在表视图的-tableView:heightForRowAtIndexPath:委托方法中,我们需要根据textHeight计算文本视图的单元格的新高度。

首先,我们需要将文本视图单元格的高度调整为最大可用高度(减去表视图中所有其他单元格的高度)。然后我们检查textHeight是否大于计算的高度。

代码语言:javascript
复制
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{   
    CGFloat heightForRow = 44.0;

    if ([indexPath row] == kRowWithTextViewEmbedded)
    {
        CGFloat tableViewHeight = [tableView bounds].size.height;
        heightForRow = tableViewHeight - ((kYourTableViewsNumberOfRows - 1) * heightForRow);

        if (heightForRow < textHeight) 
        {
            heightForRow = textHeight;
        }
    }

    return heightForRow;
}

为了获得更好的用户体验,将表格视图的content insets For bottom设置为50.0。

我已经在使用iOS 4.2.1的iPad上进行了测试,并按预期工作。

弗洛里安

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4015557

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档