首页 > 解决方案 > 具有自动布局和滚动功能的奇怪 TextView 行为

问题描述

我正在尝试构建一个与 iMessage/WhatsApp 类似的 TextView,即随着内容的增长而高度增长的 textView,但一旦达到特定高度,它也允许滚动。

我将 textView 设置为 [8,0,8,0] 的 textContainerInsent 和 38 的高度,并且能够随着内容的增加使用自动布局轻松调整 TextView 的大小。

当我尝试启用滚动时,问题就来了。每当我的 textView 有一个新的文本行时,我的 textContainerInsent 就会感到困惑并向上“推”我的文本(这意味着第一行文本被剪切为 TextView 之外的一半)。出于某种更奇怪的原因,这种情况只发生在每隔一行(所以在第 2、第 4、第 6 等)。

这也只发生在新行的第一个字符处,并在后续字符处重新定位(参见图片)。

我能够通过将我的顶部 textContainerInsent 强制为偶数行的 16 ([16,0,8,0]) 并将其保持为奇数行的 [8,0,8,0] 来破解一些东西。

然而,这远非理想,因为:

知道是什么原因造成的吗?我对 textContainerInsents/TextView 或 ContentSize 有误解吗?您对此根本原因的任何想法将不胜感激(并且不要过多地关注我的黑客行为......无论如何我都想摆脱它)。

我找到了以下有用的线程,但我尝试了建议的答案,但它们对我不起作用(因为我不想删除所有填充并希望保持滚动启用):

如何在 UITextView 中丢失边距/填充?

文本换行到下一行时 ContentInsent 太高 ContentInsent 在下一个字符的正确位置快速返回

    // Called by textViewDidChange delegate
    @objc func handleTextViewSearch() {

        let maxTextViewHeight : CGFloat = 180

        textView.isScrollEnabled = true
        textView.showsVerticalScrollIndicator = true

        textView.textContainerInset = UIEdgeInsetsMake(8, 0, 8, 0)

        let sizeHeight = min(maxTextViewHeight, textView.contentSize.height )

        // This is my textView Height Constraint

        viewHeightConstraint.constant = sizeHeight
        textView.contentOffset = CGPoint(x: 0, y: 0)

        // This my hack to manually "push" my text back when it jumps by increasing my textContainerInsent to [16,0,8,0]... It almost fixes the issue but doesn't address the root cause for the weird TextView behavior...

        if textView.contentSize.height > textView.frame.height && textView.contentSize.height <= (maxTextViewHeight - 10) {


            // Weird micro readjustment: When line goes from 1 to 2, need to increase insent by another 8 points but only when going from odd to even lines (go figure)...

            var insentAdjustment : CGFloat = 0
            let linesNumber = numberOfLines(textView: textView)
            if linesNumber % 2 == 0 {
                print("Is even number")
                insentAdjustment = 8
            } else if linesNumber == 1 {
                insentAdjustment = 8
            }

            textView.frame.size.height = textView.contentSize.height
            textView.textContainerInset = UIEdgeInsetsMake(8 + insentAdjustment, 0, 8, 0)


            print("Post update TextView: ", textView)
        }
     }

标签: swiftautolayouttextview

解决方案


推荐阅读