添加文本和禁用滚动时如何使 UITextView 字段扩展?

Posted

技术标签:

【中文标题】添加文本和禁用滚动时如何使 UITextView 字段扩展?【英文标题】:How do I get UITextView field to expand when adding text and scrolling is disabled? 【发布时间】:2018-08-15 17:36:17 【问题描述】:

我在 tableView 单元格中使用 UITextView 来保存不同大小的文本内容,并禁用滚动。

为了自动调整 UITextView 的大小,我使用了自动布局将其固定到布局中,并添加了此方法来调整高度:

 override func viewWillAppear(_ animated: Bool) 
    tableView.estimatedRowHeight = 50
    tableView.rowHeight = UITableViewAutomaticDimension
 

这在初始视图上正常工作 - 当内容首次加载时。但是,我还希望用户能够在点击内容时编辑文本(类似于 Apple Reminders 应用程序)。这可以正常工作,但有一个限制:UITextView 不会随着内容的增长而扩展。

如何让 UITextView 在编辑过程中无需滚动即可展开?

新细节: 这是当前设置的屏幕截图。

根据以下 Matt 的建议,我创建了以下子类。

class MyTextView: UITextView 

        @IBOutlet var heightConstraint : NSLayoutConstraint?
        override func awakeFromNib() 
            super.awakeFromNib()
            self.heightConstraint?.isActive = false
        

我不得不修改强制展开以避免致命错误。

【问题讨论】:

我推荐使用github.com/KennethTsang/GrowingTextView 框架,效果很好 这看起来可以很好地解决问题,但我想做一些原生的事情。如果没有其他方法,我会这样做。谢谢。 【参考方案1】:

如何让 UITextView 在编辑过程中无需滚动即可展开

自动调整大小的文本视图非常简单;对于没有高度限制的非滚动文本视图,它是默认值。在此示例中,我添加了一些代码来删除现有的高度约束,尽管您可以在情节提要中通过指示高度约束是一个占位符来做到这一点:

class MyTextView : UITextView 
    @IBOutlet var heightConstraint : NSLayoutConstraint!
    override func awakeFromNib() 
        super.awakeFromNib()
        self.heightConstraint.isActive = false
    

结果截图:

如果您随后对表格视图进行批量更新,并假设单元格的其他内部约束是正确的,那么单元格也将被重新测量(但我没有在示例中演示)。

【讨论】:

嗨,马特,这可以实时工作吗?当我输入时它会自动扩展 TextView 区域吗? 当我将它添加到实现 UITextView 的 TableView 控制器时,我得到三个错误,第一个是“方法没有覆盖其超类中的任何方法”。另一个是“UITableViewController has no member layoutSubviews”和“no member contentSize”。您能否提供有关正确实施的更多见解? 好吧,如果您将代码添加到表格视图控制器中,那么您没有按照我说的去做。试试看我说的。 对不起,我的代码错误,已修复。事实证明,self-sizing 是默认设置;除了关闭高度限制之外,您无需执行任何操作。 请看我上面的笔记。我尝试了你所说的,它抛出了一个致命错误,所以我删除了强制解包并将其设为可选。你的例子正是我正在寻找的,所以如果我们能得到最后一点调整,那就完美了。【参考方案2】:

每个人都非常努力地试图帮助我解决这个问题。我尝试了每一个,但都无法以令人满意的结果实施。

一位同事向我介绍了这个解决方案:https://***.com/a/36070002/152205,并且通过以下修改能够解决我的问题。

    // MARK: UITextViewDelegate
    func textViewDidChange(_ textView: UITextView) 
        let startHeight = textView.frame.size.height
        let calcHeight = textView.sizeThatFits(textView.frame.size).height

        if startHeight != calcHeight 

            UIView.setAnimationsEnabled(false)
            self.tableView.beginUpdates()
            self.tableView.endUpdates()

          // let scrollTo = self.tableView.contentSize.height - self.tableView.frame.size.height
          // self.tableView.setContentOffset(CGPoint(x: 0, y: scrollTo), animated: false)

            UIView.setAnimationsEnabled(true)
        
    

注意:scrollTo 选项导致内容向上移动几个单元格。删除后,一切都按预期工作。

【讨论】:

【参考方案3】:

你可以使用 var sizeThatFits

override func viewDidLoad() 
    super.viewDidLoad()
    textView = UITextView()
    textView.sizeThatFits(CGSize(width: textView.frame.size.width, height: textView.frame.size.height))

【讨论】:

以上是关于添加文本和禁用滚动时如何使 UITextView 字段扩展?的主要内容,如果未能解决你的问题,请参考以下文章

当键盘可见时如何使 UITextView 一直滚动到底部

当新行添加到 UITextView 实例中时,如何向上滚动视图?

UITextView 代表禁用滚动

UITextView如何禁用带有内容插入的水平滚动

禁用 UITextView 中的滚动,同时避免在 ios 的当前位置弹跳到顶部和文本不可见

如何在输入/编辑时使 UITextView 滚动