Toggle 在最大行数后启用 UITextView 滚动

Chr*_*ris 0 uitextview uitextviewdelegate ios nslayoutconstraint swift

uitextview subview在 inputContainerView 中有一个,因为它可能出现在消息传递应用程序中。

以编程方式,在加载uitextview时,初始化 inputContainerView 时设置的高度锚点。当输入更多行文本时,此约束在增加容器高度方面非常有效。

我的目标是uitextview在达到 X 行之后限制其高度,此后键入的任何行都可以滚动。同样,当行数低于最大值时,它会返回到其原始形式 - 不可滚动并根据内容自动调整高度。

经过多次试验和研究,一旦达到最大行数,我就设法获得了注视的高度,但是一旦行数低于最大值,我似乎无法弄清楚如何将其恢复到原始形式。看起来uitextview高度停留在行数达到最大值的高度。

下面是相关代码:

//Container View Initialization, onLoad Frame Height is set to 60
override init(frame: CGRect) {
super.init(frame: frame)
autoresizingMask = .flexibleHeight

addSubview(chatTextView)
textView.heightAnchor.constraint(greaterThanOrEqualToConstant: frame.height - 20).isActive = true
}

//TextView Delegate

var isTextViewOverMaxHeight = false
var textViewMaxHeight: CGFloat = 0.0

func textViewDidChange(_ textView: UITextView) {
    let numberOfLines = textView.contentSize.height/(textView.font?.lineHeight)!

    if Int(numberOfLines) > 5 {

        if !isTextViewOverMaxHeight {
            containerView.textView.heightAnchor.constraint(greaterThanOrEqualToConstant: 40).isActive = false
            containerView.textView.heightAnchor.constraint(equalToConstant: 
            containerView.textView.frame.height).isActive = true
            containerView.textView.isScrollEnabled = true                

            textViewMaxHeight = containerView.textView.frame.height
            isTextViewOverMaxHeight = true
        }
    } else {

        if isTextViewOverMaxHeight {
            containerView.textView.heightAnchor.constraint(equalToConstant: textViewMaxHeight).isActive = false
            containerView.textView.heightAnchor.constraint(greaterThanOrEqualToConstant: 40).isActive = true
            containerView.textView.isScrollEnabled = false                

            isTextViewOverMaxHeight = false
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

San*_*ari 5

你手头的一个简单问题过于复杂,这是你如何实现你想要的

class ViewController: UIViewController {
    var heightConstraint: NSLayoutConstraint!
    var heightFor5Lines: CGFloat = 0

    override func viewDidLoad() {
        super.viewDidLoad()
        let textView = UITextView(frame: CGRect.zero)
        textView.delegate = self
        textView.backgroundColor = UIColor.red
        textView.translatesAutoresizingMaskIntoConstraints = false
        self.view.addSubview(textView)
        textView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true
        textView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true
        textView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor).isActive = true
        heightConstraint = textView.heightAnchor.constraint(equalToConstant: 30.0)
        heightConstraint.isActive = true
    }
}


extension ViewController: UITextViewDelegate {
    func textViewDidChange(_ textView: UITextView) {
        let numberOfLines = textView.contentSize.height/(textView.font?.lineHeight)!

        if Int(numberOfLines) > 5 {
            self.heightConstraint.constant = heightFor5Lines
        } else {
            if Int(numberOfLines) == 5 {
                self.heightFor5Lines = textView.contentSize.height
            }
            self.heightConstraint.constant = textView.contentSize.height
        }
        textView.layoutIfNeeded()
    }
}
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

这是如何工作的?:

很简单,你的 textView 以一些高度开始(这里需要高度约束,因为我既没有禁用它的滚动,也没有提供底部约束,所以它没有足够的数据来评估它的内在高度)并且每次文本更改时您检查行数,只要行数小于阈值行数,您就会不断增加 textView 的高度约束,使其框架与 contentSize 匹配(因此没有滚动),并且一旦达到预期的行数,您限制高度,以便 textView 框架小于实际内容大小,因此会自动滚动

希望这可以帮助