调整 UITextView 和包含它的部分而不过度绘制下一个 tableview 部分

Posted

技术标签:

【中文标题】调整 UITextView 和包含它的部分而不过度绘制下一个 tableview 部分【英文标题】:Resizing UITextView and the section containing it without overdrawing next tableview section 【发布时间】:2015-09-01 09:05:34 【问题描述】:

我有一个包含四个部分的静态表。第三部分包含一个 UITextView,如果用户输入多于一行,我想调整它的大小。我设法让它工作,但我调整大小的 textView 过度绘制了最后一个表格部分。

我发现了很多关于这方面的旧文章都有不同的解决方案,但对于我的静态表来说,没有一个真正适合我。

我所做的是让我的控制器实现 UITextViewDelegate 并编写了这个方法:

func textViewDidChange(textView: UITextView) 
    var frame = textView.frame
    frame.size.height = textView.contentSize.height
    textView.frame = frame

    tableView?.beginUpdates()
    tableView?.endUpdates()

有些文章建议写一个高度约束,然后把它放在上面的方法中:

let size = reminderNameTextInput.bounds.size
let newSize = reminderNameTextInput.sizeThatFits(CGSize(width: size.width, height: CGFloat.max))

// Resize the cell only when cell's size is changed
if size.height != newSize.height 
    UIView.setAnimationsEnabled(false)
    tableView?.beginUpdates()
    tableView?.endUpdates()

不管怎样,结果都是一样的:textView 增长并过度绘制下一个 tableview 部分。

我该如何解决这个问题?

更新 1: 让我告诉你我所说的“过度生长”它下面的部分是什么意思:

更新 2 如果我重新计算 heightForRowAtIndexPath 中的单元格高度,就会发生这种情况。它完全覆盖了它下面的部分,而不是向下移动它们:

【问题讨论】:

【参考方案1】:

以下代码适用于与您相同的用例,将其放在 textViewDidChange 中:

let size = textView.bounds.size

let newSize = textView.sizeThatFits(CGSize(width: size.width, height: CGFloat.max))
var estimatedHeight = newSize.height > MINIMUM_HEIGHT ? newSize.height : MINIMUM_HEIGHT

textView.frame = CGRectMake(0, 0, textView.frame.width, estimatedHeight)
UIView.setAnimationsEnabled(false)
tableView?.beginUpdates()
tableView?.endUpdates()
UIView.setAnimationsEnabled(true)

【讨论】:

谢谢。你把这段代码放在哪里?在 textViewDidChange 函数中? “self.frame”中的“self”是什么? 是的,在 textViewDidChange 中。框架是文本视图。出于我的目的,我对其进行了子类化,为澄清而进行了编辑。 这与我的代码做同样的事情 - 它以一种不太好的方式在下一个表视图部分增长 textView。 (而不是随着不断增长的 UITextView 向下移动剩余部分。) 问题出在其他地方。没有看到更多的代码/故事板设置,一切都是在黑暗中拍摄。 当您将文本预设为 lorem ipsum 或同样长的内容(几行文本)时会发生什么,它的行为是否正确?在 heightForRowAtIndexPath 中,尝试添加if indexPath.row == TEXT_VIEW_CELL_INDEX_PATH return self.textViewCell.estimatedHeight 【参考方案2】:

您是否使用自动布局? 使用 autolayouts 和 size-classes 时,您可以从 storyboard 解决问题

UITextView 约束设置:

    设置左、右、上、下边距约束 将 Content Compression Resistance Prority 的优先级从 750 更改为 900 或高于 750 以及 Content Hugging Priority 250 t0 260。

    关闭启用滚动。

    你还必须在textViewDidChange(textView: UITextView)方法中添加以下行,

    tableView?.beginUpdates() tableView?.endUpdates()

然后应该工作!

【讨论】:

似乎不起作用。 textView 现在根本没有增长。我在 UITextView 上设置了约束,这导致了 2 个垂直和 2 个水平空间约束(分别在内容视图和文本视图上)。然后我设置 UITextView 的 Content Hugging 和 Compression 阻力优先级,正如您在开始和结束更新中指定的那样。 'Scrolling Enabled' 也必须从情节提要中取消选择。如果不这样做,它可能不起作用。 UITextView 仍然没有增长。现在文本刚刚超出屏幕的可见区域。使用后退箭头,我必须向后移动,以便再次看到光标。但是 textView 没有增长。

以上是关于调整 UITextView 和包含它的部分而不过度绘制下一个 tableview 部分的主要内容,如果未能解决你的问题,请参考以下文章

调整包含 UITextView 的 UICollectionViewCell 以适合 contentSize

UITextView 不为 iPhone 调整大小

如何根据内容调整 UITextView 的大小,宽度固定

UITextView 调整宽度以适合文本

如何使节标题中的 UITextView 将其高度调整为其内容

如何在不调整大小的情况下旋转 UITextView?