在textfield中显示文本有一种奇怪的行为

时间:2016-06-27 11:47:35

标签: ios swift uitextfield

我试图创建一个特定的文本字段。任何聊天应用程序都有一个文本字段,您可以在其中编写消息并发送它。该字段在变为可滚动之前将其高度增加到3行文本。

就我而言,文本字段是这样的:

enter image description here

在橙色中它是文本区域,在右侧,您可以看到包含图像视图的发送按钮。所有这些元素都包含在您可以在文本字段中查看的视图中。

唯一的高度限制是放在文本字段上。

使用以下代码调整文本字段的高度到其内容的高度:

func textViewDidChange(textView: UITextView)
    {

        contentSize = textField.contentSize.height

        if(previousContentSize != contentSize)
        {
            //textField.sizeThatFits(CGSize(width: view.bounds.width - 55, height: 0))
            heightTextfieldConstraint.constant = textField.contentSize.height
        }

        previousContentSize = contentSize

    } 

在文本字段中的每个更改中都会调用此函数。

它有效,但是以一种奇怪的方式。确实当第二行返回时,文本显示如下:

enter image description here

然后当第三行返回时:

enter image description here

为什么有第二行时contentInset Top不好,有第三行时为good?

我已尝试使用sizeToFit(),但我没有取得任何好成绩。

1 个答案:

答案 0 :(得分:1)

我刚才遇到了同样的麻烦。以下是来自blog post撰写的Adam Siton的解决方法。

这个想法是在帧更改后正确更新contentOffset到中心文本。这是解决方法示例。

final class AutoGrowingTextView: UITextView {

    @IBInspectable var minHeight: CGFloat = 20
    @IBInspectable var maxHeight: CGFloat = 90

    var heightConstraint: NSLayoutConstraint!

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.setup()
    }

    override func awakeFromNib() {
        super.awakeFromNib()
        setup()
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        handleAutoLayouts()
        centerVertically()
    }

    private func handleAutoLayouts() {
        var intrinsicSize = self.intrinsicContentSize()
        intrinsicSize.height = max(intrinsicSize.height, minHeight);
        intrinsicSize.height = min(intrinsicSize.height, maxHeight);

        heightConstraint.constant = intrinsicSize.height
    }

    private func centerVertically() {
        // We're  supposed to have a maximum height contstarint in code for the text view which will makes the intrinsicSide eventually higher then the height of the text view - if we had enough text.
        // This code only center vertically the text view while the context size is smaller/equal to the text view frame.
        if intrinsicContentSize().height <= self.bounds.size.height {
            var topCorrect = (self.bounds.size.height - self.contentSize.height * zoomScale) / 2
            topCorrect = ( topCorrect < 0.0 ? 0.0 : topCorrect )
            self.contentOffset = CGPointMake(0, -topCorrect)
        }
    }

    override func intrinsicContentSize() -> CGSize {
        var intrinsicContentSize = self.contentSize
        intrinsicContentSize.width += (textContainerInset.left + textContainerInset.right ) / 2
        intrinsicContentSize.height += (textContainerInset.top + textContainerInset.bottom) / 2
        return intrinsicContentSize
    }

    private func setup() {
        for const in constraints {
            if const.firstAttribute == .Height {
                heightConstraint = const
                break
            }
        }
    }
}