UITextView在UITableViewCell中平滑自动调整大小,在iPad上显示和隐藏键盘,但适用于iPhone [英] UITextView in a UITableViewCell smooth auto-resize shows and hides keyboard on iPad, but works on iPhone

查看:97
本文介绍了UITextView在UITableViewCell中平滑自动调整大小,在iPad上显示和隐藏键盘,但适用于iPhone的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have implemented a custom UITableViewCell which includes a UITextView that auto-resizes as the user types, similar to the "Notes" field in the Contacts app. It is working properly on my iPhone, but when I am testing it in the iPad, I am getting some very strange behavior: When you get to the end of a line, the keyboard hides for a millisecond and then shows itself again immediately. I would write it off as just a quirky bug, but it actually causes some data loss since if you are typing, it loses a character or two. Here's my code:

// 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;
}



问题



所以,这就是发生的事情

The Problems

So, here's what's happening


  1. 这段代码在我的iPhone和iPhone模拟器上正常工作。当我输入文本时,UITextView会顺利增长,UITableViewCell也会随之增长。

  2. 然而,在iPad模拟器上,它变得棘手了。当你在第一行输入时它工作正常,但是当你到达一行的末尾时,键盘会消失,然后立即重新出现,这样如果用户继续输入应用程序就会错过一两个字符。

  3. 这里有一些关于我注意到的奇怪行为的补充说明可能有助于解释它:


    • 另外,我发现了删除行 [myTableView beginUpdates];函数中的[myTableView endUpdates]; textViewDidChange:(UITextView *)textView 使UITextView正常生长,也不显示和隐藏键盘但不幸的是,UITableViewCell没有增长到合适的高度。

    • 更新:关注这些说明,我现在能够阻止文本的奇怪运动;但键盘仍然隐藏和显示,这很奇怪。

  1. This code is working 100% properly on my iPhone and in the iPhone simulator. As I type the text, the UITextView grows smoothly, and the UITableViewCell along with it.
  2. On the iPad simulator, however, it gets screwy. It works fine while you are typing on the first line, but when you get to the end of a line, the keyboard disappears and then reappears immediately, so that if the user continues typing the app misses a character or two.
  3. Here are some additional notes on the weird behaviors that I have noticed which may help explain it:
    • Also, I have found that removing the lines [myTableView beginUpdates]; [myTableView endUpdates]; in the function textViewDidChange:(UITextView *)textView makes the UITextView grow properly and also doesn't show and hide the keyboard, but unfortunately, then the UITableViewCell doesn't grow to the proper height.
    • UPDATE: Following these instructions, I am now able to stop the strange movement of the text; but the keyboard is still hiding and showing, which is very strange.

有没有人对如何让键盘不断显示有任何想法,而不是在iPad到达终点时隐藏和显示?

PS:我对使用ThreeTwenty不感兴趣。

P.S.: I am not interested in using ThreeTwenty.

推荐答案

你应该在NO中返回NO:

you should return NO in:

 -(BOOL) textViewShouldEndEditing:(UITextView *)textView

如果您想随时显示键盘。你应该通过向这个委托函数返回YES来处理应该隐藏键盘的情况。

if you would like to show keyboard at all times. You should handle cases, which keyboard should be hidden, by returning YES to this delegate function.

编辑:

我挖了一点,当 [tableView endUpdates] 调用时,它基本上做了3件事:

I dug a little more, when [tableView endUpdates] called, it basically does 3 things :


  1. 禁用 tableView上的用户交互

  2. 更新单元格更改

  3. tableView上启用用户交互

  1. Disables user interaction on the tableView
  2. Updates cell changes
  3. Enables user interaction on the tableView

SDK(平台)之间的区别在于 [UIView setUserInteractionEnabled] 方法。由于UITableView不会覆盖 setUserInteractionEnabled 方法,因此从super(UIView)调用它。

The difference between SDKs(platforms) is at [UIView setUserInteractionEnabled] method. As UITableView does not overrite setUserInteractionEnabled method, it is called from super (UIView).

setUserInteractionEnabled 调用时,iPhone ,查找私有字段 _shouldResignFirstResponderWithInteractionDisabled ,默认返回 NO ,因此不会重新签名第一个响应者(UITextView)

iPhone when setUserInteractionEnabled called, looks for a private field _shouldResignFirstResponderWithInteractionDisabled which returns NO as default, so does not resign the first responder (UITextView)

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

But on iPad there is no such check AFAIK, so it resignes UITextView on step 1, and sets focus and makes it first responder on step 3

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

Basically, textViewShouldEndEditing, which allows you to keep focus, according to SDK docs, is your only option ATM.


当要求文本
视图重新签署第一个
响应者状态时,将调用此方法。当用户尝试将
编辑焦点更改为另一个控件时,可能会发生

在焦点实际变化之前,
然而,文本视图调用这个
方法给你的代表一个机会
来决定它是否应该。

This method is called when the text view is asked to resign the first responder status. This might occur when the user tries to change the editing focus to another control. Before the focus actually changes, however, the text view calls this method to give your delegate a chance to decide whether it should.

这篇关于UITextView在UITableViewCell中平滑自动调整大小,在iPad上显示和隐藏键盘,但适用于iPhone的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆