在启用滚动的堆栈视图中扩展 UITextView

Posted

技术标签:

【中文标题】在启用滚动的堆栈视图中扩展 UITextView【英文标题】:Expanding UITextView inside a Stack View with scrolling enabled 【发布时间】:2017-10-26 23:45:54 【问题描述】:

我正在尝试使用 Auto Layout 和 Stackview 来实现一些目标。我有一个带有 UIView、UITextView 和 UIView 的 Vertical Stackview,如下所示。

我在这里查看了之前的答案,但找不到一个干净的解决方案来实现这一点。

UITextView 是可编辑的,并且必须在用户输入时扩展 - 为此我在 IB 中禁用了 UITextView 的滚动。我还在 UITextView 上设置了一个高度约束,设置为“大于或等于”10,行数设置为 0,以便UITextView 在用户键入时在运行时采用固有高度。我还希望 UITextView 的扩展继续进行,直到 UIStackView 底部边缘到达键盘附件的顶部边缘。我已经能够通过将堆栈视图固定到 Superview 的顶部、尾部和前缘来实现扩展 UITextView 部分,但我一直收到一个错误,即 stackview needs Y position or height 这是可以理解的,但如果我给它一个固定高度或底部约束,则 UITextView 根本不会展开。

我也不确定当 UITextView 到达键盘辅助视图的顶部边缘时如何停止它的扩展。

我目前的代码是

let allowedHeight = self.view.frame.height - (self.keyboardHeight! + self.accessory.frame.height)

基本上是通过减去keyboardheight+Accessory视图高度来找到视图框架中允许的高度。这个计算正确地发生了。接下来我这样做(在textViewDidChange 内)希望仅启用/禁用UITextView 上的滚动会起作用,但显然它不起作用,因为整个文本视图会随着每次击键而奇怪地上下跳跃。

func textViewDidChange(_ textView: UITextView) 
   if stackView.frame.height >= allowedHeight
            textView.isScrollEnabled = true
        

   if stackView.frame.height < allowedHeight
            textView.isScrollEnabled = false
        

实现我的目标的最佳方式是什么?

【问题讨论】:

【参考方案1】:

情侣笔记...

我认为你最好设置UITextView 的最大高度而不是UIStackView。 Text View 将根据其内容展开/收缩,因此您可以设置&lt;= 高度约束。

计算“elementsHeight” - 顶部和底部视图使用的垂直尺寸,加上任何间距 - 并将“最大文本视图高度”设置为视图高度减去 elementsHeight ...并在可见时减去键盘高度。

当“最大文本视图高度”改变时更新文本视图的高度约束常量。

然后为文本视图的.contentSize 设置一个观察者...并根据.contentSize.height 与“最大文本视图高度”相比启用/禁用滚动。

需要一些跳跃,以确保您在布局子视图时更新大小,并确保您不会陷入递归循环。

我是这样设置的:

文本视图的初始高度约束是&lt;= 40 - 但这并不重要,因为每次视图布局不同时都会通过代码进行更改。

我在 GitHub 上提供了一个示例——它有效,但实际上只是一个起点。有兴趣可以看一下,拆开看看。 https://github.com/DonMag/ExpandingTextView

【讨论】:

感谢代码。我会试试看。 这是完美的工作。 iphone X 的一个警告。由于某种原因,iPhone X 中的安全区域默认情况下会在 y 偏移上增加 22 点,因此仅添加 stackview 的 y 偏移会将键盘后面的整个东西向下推 22px。不是世界末日,而且很容易修复。再次感谢您!

以上是关于在启用滚动的堆栈视图中扩展 UITextView的主要内容,如果未能解决你的问题,请参考以下文章

滚动视图和堆栈视图

嵌入堆栈视图时,滚动视图内容未填充

如何以编程方式在滚动视图中嵌入堆栈视图

如何在设置了“等宽”的滚动视图中嵌入的堆栈视图中将标签文本设置为远离视图边缘?

具有嵌入式堆栈视图的滚动视图在编程上失败

如何在 Swift IOS 中创建具有多个堆栈视图的可滚动堆栈视图