UITableView在自动调整TextView中input文本时闪烁/口吃
目前我有一个调整UITextView
的UITableView
。 单元格正在使用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; }