UITableView在自动调整TextView中input文本时闪烁/口吃

目前我有一个调整UITextViewUITableView 。 单元格正在使用beginUpdates / endUpdates自动resize,但是当它执行时,表格视图会出现断断续续的情况(请参阅下面的gif)。

最终的结果是一个UITableViewCell ,其中有一个textview,根据它的内容resize。 这里是自定义的UITableViewCell类中的代码,它使UITableView自身更新。

 - (void)textViewDidChange:(UITextView *)textView { // This is a category on UITableViewCell to get the [self superView] as the UITableView UITableView *tableView = [self tableView]; if (tableView){ [tableView beginUpdates]; [tableView endUpdates]; } } 

以下是我已经试过的东西:

获取当前contentOffset并在endUpdates后重置它,但没有工作在更新之前禁用滚动的UITableView ,然后启用后,我试图返回NO总是从- (BOOL)textViewShouldEndEditing:(UITextView *)textView我的UITableView细胞高度是使用UITableViewAutomaticDimension 。 任何其他的想法或想法是受欢迎的。

下面是它的样子:

表视图口吃

我不想使用任何库,所以请不要提出任何build议。

谢谢

编辑:解决scheme

发现这里: 我不想在开始更新animation,结束更新块为uitableview?

感谢@JeffBowen提供了一个很好的发现(尽pipe它是可行的,并且允许我仍然实现支持iOS 7的UITableViewDelegate方法)。 执行更新之前closuresanimation,然后在更新之后启用以防止UITableView卡住。

 [UIView setAnimationsEnabled:NO]; [tableView beginUpdates]; [tableView endUpdates]; [UIView setAnimationsEnabled:YES]; 

如果您不需要使用委托方法,并且只需要iOS 8+的简单解决scheme,那么请使用@ Massmaker的答案。

我的解决scheme(对于iOS 8)首先在我的viewController viewDidLoad

 self.tableView.rowHeight = UITableViewAutomaticDimension; // this line is needed to cell`s textview change cause resize the tableview`s cell self.tableView.estimatedRowHeight = 50.0; 

然后, 在Swift中结合这篇文章的解决scheme,以及我在单元格中设置的一些肮脏的想法

 @property (nonatomic, strong) UITableView *hostTableView; 

并在cell -s -(void) textViewDidChange:(UITextView *)textView

  CGFloat currentTextViewHeight = _textContainer.bounds.size.height; CGFloat toConstant = ceilf([_textContainer sizeThatFits:CGSizeMake(_textContainer.frame.size.width, FLT_MAX)].height); if (toConstant > currentTextViewHeight) { [_hostTableView beginUpdates]; [_hostTableView endUpdates]; } 

然后在viewController

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath textCell.hostTableView = self.tableView; 

高度变化后

只需在调用beginUpdates之前禁用animation,并在调用endUpdates之后重新启用它。

 [UIView setAnimationsEnabled:NO]; [tableView beginUpdates]; [tableView endUpdates]; [UIView setAnimationsEnabled:YES]; 

绝对是一个黑客,但现在工作。 感谢我的朋友Beau指出了这一点 。

我没有find一个方法来实现它,因为:当你触发[tableView endUpdates],表重新计算contentSize并重新设置它。 这导致将contentOffset重置为默认值。

这是从UIScrollViewinheritance的行为,我试图避免它通过:

  • inheritanceUITableView并覆盖setContentOffset:setContentOffset:animated函数。 但是当表视图改变contentSize的时候他们不会调用。
  • 子类化UITableView,重写setContentSize:函数并将contentOffset设置为旧值,在内容大小更新后,但它不适用于我
  • 使用KVO,并重置后设置旧值contentOffset,但无论如何,我有这个animation的问题
  • 将scrollEnabled设置为NO并将scrollToTop设置为NO,但这也无济于事

如果有人find这个问题的解决scheme欢迎。 也许可能的解决scheme – 禁用自动布局: iOS:setContentSize导致我的整个UIScrollView框架跳转

更新:我find解决scheme:直接更改单元格高度,内容大小和内容偏移量:这对我来说(表格视图是单元格的UITextView委托)

 - (void)textViewDidChange:(UITextView *)textView { CGFloat textHeight = [textView sizeThatFits:CGSizeMake(self.width, MAXFLOAT)].height; if (self.previousTextHeight != textHeight && self.previousTextHeight > 0) { CGFloat difference = textHeight - self.previousTextHeight; CGRect cellFrame = self.editedCell.frame; cellFrame.size.height += difference; self.editedCell.frame = cellFrame; self.contentSize = CGSizeMake(self.contentSize.width, self.contentSize.height + difference); self.contentOffset = CGPointMake(self.contentOffset.x, self.contentOffset.y + difference); } self.editedNote.comments = textView.text; }