您好:这一直困扰着我一整天,但我只是把一些我认为已经破解的东西放在一起。我假设您知道如何将基本的 tableView 放在一起。
您需要为每一行添加一个 UITextView,并且至关重要的是,让您的 tableViewController 成为每个 UITextView 的委托。除了每一行的字符串值数组外,您还需要每行都有一个高度数组(CGFloats)。另一个关键方面是为每个 textView 分配一个与单元格的 indexPath.row 相等的数字标签,这使我们能够跟踪我们正在处理的 textView。这将作为一个相同值的数组开始,但想法是当文本变得对于现有框架而言太大时,您可以根据需要更新此数组,如下所示。
然后我实现了以下两个委托函数以及一个定制函数,以根据需要更新布局:
func updateLayout(forTextView: UITextView) -> Void {
guard forTextView.tag < self.data.count else { return } // Make sure we're not going to try and access a value that does not exist
self.data[forTextView.tag] = forTextView.text // Update our data array to reflect the new string value for the cell's text view
let newHeight : CGFloat = forTextView.frame.height // The new cell height is based on the height of the text view
let oldHeight : CGFloat = self.tableView.cellForRowAtIndexPath(NSIndexPath(forRow: forTextView.tag, inSection: 0))!.frame.height // Retrieving the existing height of the cell
self.heights[forTextView.tag] = newHeight + 2 // Set the new value in the heights array with a 1 point buffer
// Now animate to ease the transition
UIView.animateWithDuration(0.25) {
for cell in self.tableView.visibleCells {
if let indexPath = self.tableView.indexPathForCell(cell) {
// We only need to update the edited cell and all cells below it
if indexPath.row > forTextView.tag {
cell.frame = CGRect(origin: CGPointMake(cell.frame.origin.x, cell.frame.origin.y + forTextView.frame.height + 2 - oldHeight), size: CGSizeMake(cell.frame.width, self.heights[indexPath.row]))
}
else if indexPath.row == forTextView.tag
{
cell.frame = CGRect(origin: cell.frame.origin, size: CGSizeMake(cell.frame.width, self.heights[indexPath.row]))
}
}
}
}
}
func textViewDidEndEditing(textView: UITextView) {
// Update the cell and exit
self.updateLayout(textView)
}
func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
// More complicated: we need to update the frame but also maintain focus in this textView as the user has not finished editing yet
var textFrame : CGRect = textView.frame
let newHeight : CGFloat = ceil(textView.contentSize.height)
if newHeight - textFrame.height > 0 {
textFrame.size.height = ceil(textView.contentSize.height)
textView.frame = textFrame
textView.setContentOffset(CGPointMake(0, 5), animated: false)
self.updateLayout(textView)
}
// This code puts an active cursor back at the end of the textView's text
textView.selectedRange = NSRange(location: textView.text.characters.count, length: 0)
textView.becomeFirstResponder()
return true
}
棘手的部分是更新 tableView 的布局,同时将光标的焦点保持在正在积极编辑的字段中。
我对在文本字段需要扩展时提供平滑过渡的结果感到非常满意。
我不想把完整的代码发给你,因为最好自己把这些东西放在一起;但是,如果您真的被卡住了,请给我留言,我会发送给您。万事如意!