在iOS中的UITableViewCell中自动扩展文本输入

在iOS中动态扩展视图从未如此简单。 正如我们在iOS的早期版本中所看到的,如果我们需要一个UILabel来根据其内容高度来计算高度,我们可以这样做,但是需要基于内容文本,字体,UILabel宽度等进行一些手动高度计算。它通过调用sizeToFit方法来增长。

对于文本输入,这从来都不是一件容易的事。 如果我们使用UITextField ,我们知道它最多只能输入一行。 对于多行输入,我们使用UITextView并使它可编辑。 但是问题是,我们必须设置它的高度或边界约束。 如果输入内容的高度超过了UITextView的高度,则它不会扩展,而是在该高度内内容可以滚动。 UITableViewCell的动态高度计算更加复杂。 但是在具有自动布局功能的iOS 8之后,生活变得更加轻松,因为苹果终于对它进行了外观设计。

好吧,这里的要求有些不同。 我们需要一个文本输入视图,该视图会随着内容高度的变化而自动增长/缩小。 这是操作方法。

首先,让我们创建一个Xcode项目并添加UITableViewCell的新子类。 说,我们的子类名称是QACell。 因此,让我们打开QACell.xib并根据您的要求添加TextView或UITextView的任何子类。

让我们在UITextView的顶部,底部,左侧,右侧添加边界约束,以便当UITableViewCell的高度发生变化时,其高度可以增加/缩小。 因此,添加约束后,它应该看起来像这样。

现在,打开UITextView的“属性”检查器,并禁用“滚动和弹跳”。 我们必须禁用滚动,因为启用滚动时,UITextView的框架与其内容大小无关。 但是当被禁用时,它们之间是有关系的。 我建议禁用跳动,因为我们需要在UITextView发生的每次更改时都更新UITableViewCell,当启用跳动并且TextView高度发生更改时,我们会有意外的跳动,这是我们所不希望的。

现在,让我们打开QACell.swift并为我们正在使用的UITextView添加一个IBOutLet。 然后是棘手的部分。 我们需要观察UITextView中内容的变化,这意味着当我们在UITextView实例中键入用户时,我们需要知道。 我们知道该怎么做,对吗? 我们需要实现UITextViewDelegate协议,并重写textViewDidChange(textView:UITextView)方法。 在这一阶段,我们知道用户何时通过委托在其中键入内容。

正如我们可以看到的变化一样,当发生变化时,我们必须通知UITableView更新当前UITableViewCell实例的高度。 但这不只是像往常一样重新加载单元格,因为如果我们重新加载单元格,则在键入每个字符之后,单元格将被重新加载,并且焦点将从当前UITextView实例中丢失。 因此,我们将无法正确键入。 而且,如此多次更新Cell绝对是一项昂贵的操作。 因此,让我们解决问题。

因为我们需要将输入更改的信息传递给我们的UITableView,所以我们将通过委托进行操作。 因此,让我们在其中编写一个协议和一个委托方法。

 协议ExpandingCellDelegate { 
func updateCellHeight(indexPath:NSIndexPath,comment:String)
}

现在,当UITextView实例的内容更改时,我们将调用委托方法。 因此,实现此协议的类(我们的ViewController)获得了更新特定UITableViewCell实例所需的消息。 在我们的代码中看起来像这样。

  func textViewDidChange(textView:UITextView){ 
self.delegate.updateCellHeight(self.cellIndexPath,注释:textView.text)
}

在这个阶段,我们已经完成了构建基础。 现在我们必须把这个事情付诸行动。 让我们打开具有UITableView的ViewController并实现UITableViewDataSource,UITableViewDelegate协议。 而且,实现我们之前创建的ExpandingCellDelegate

cellForRowAtIndexPath中为QACell设置必要的数据源和属性,并像下面的代码一样设置委托。

  cell.answerTextView.scrollEnabled = false 
cell.headerLabel.text = self.questions [indexPath.row]
cell.cellIndexPath = indexPath
cell.delegate =自我

由于我们已经设置了委托并实现了updateCellHeight委托方法,因此,当UITextView的内容更改时,我们的ViewController现在会收到通知。 因此,我们唯一要做的就是,需要使用以下代码更新或刷新Cell。

  func updateCellHeight(indexPath:NSIndexPath,comment:String){ 
self.answers [indexPath.row] =评论
self.uiTableView.beginUpdates()
self.uiTableView.endUpdates()
}

我们还没有完成,还剩下一小件事。 此方法的UITableViewCells必须具有动态高度。 在iOS 8.0之前,这很困难,但现在已经不复存在了。 让我们在ViewDidLoad方法中添加以下两行,并且不要为UITableView实现任何高度委托。

  self.uiTableView.estimatedRowHeight = 50 
self.uiTableView.rowHeight = UITableViewAutomaticDimension

让我们运行它并查看结果。

最后,如果我们认真遵循了说明,则应该在UITableViewCell中获得一个自动展开的UITextView,如下图所示。

样例代码
我编写了一个简单的iOS应用,演示了我上面描述的所有内容。 可以在我的Github存储库中找到它。