防止UITextView偏移其文本容器

时间:2018-03-28 13:46:29

标签: ios uitextview nstextcontainer

我想在用户输入文字时动态修改UITextView的高度(最大高度)。当文本视图中有偶数行时,我遇到了一种非常奇怪的行为。

我正在使用autolayout,文本视图有一个高度约束。我回复了对文本视图的委托(textViewDidChange(_:))的调用,我根据contentSize计算并调整了高度限制。

以下是代码:

func textViewDidChange(_ textView: UITextView) {
    let newHeight = textView.contentSize.height
    let newConstraintConst = max(MinTextViewHeight, min(MaxTextViewHeight, newHeight))
    self.textViewHeightConstraint.constant = newConstraintConst
}

这很有效,它会将帧的大小调整为MaxTextViewHeight,然后文本视图可以滚动。但是,如果文本视图中有偶数行,则文本视图会在其NSTextContainer的底部添加一种偏移,从而导致顶行被截断:

top line is cut off

text container is offset

然而,当有奇数行时,NSTextContainer不再偏移:

top line is normal

text container is normal

起初我以为它是以某种方式由文本视图textContainerInset控制,但仅用于填充<{>}内的空间,如将其设置为NSTextContainer会移除内部空间,但不会影响偏移(顺便说一下,因为顶线几乎完全消失,所以更糟糕):

removing the inset makes it even worse

我查看了.zero类引用,但是我没有看到任何可以让我操纵甚至获得此偏移值的属性。

作为一种解决方法,我正在增加文本容器的顶部插图并删除底部插图:

UITextView

enter image description here

到目前为止这种方法有效,但我通过反复试验得出值为10,到目前为止,我只在一台设备上测试过它。

我对需要脆弱,固定价值的更多hacky变通办法不感兴趣;我试图了解如何设置此偏移量以及修复它的正确方法。我希望有人可以提供一些见解,谢谢!

1 个答案:

答案 0 :(得分:1)

仅仅是一种推测,但我认为问题在于文本视图假定在调用textViewDidChange时其自身的高度不会改变,所以它在认为必须时滚动,无论你改变它的框架

不确定您是否认为我的解决方案过于苛刻,但是当您不想要它时,这将阻止它滚动。只要想要的内容大小小于最大大小,我就会将内容偏移固定到顶部。

只需添加:

func scrollViewDidScroll(scrollView: UIScrollView) {
    if textView.contentSize.height <= MaxTextViewHeight && textView.contentOffset.y > 0.0 {
        textView.contentOffset.y = 0.0;
    }

}