如何使用自动布局动态设置textview高度

how to set textview height dynamically using autolayout

需要像这样设置一个初始高度为 30 的文本视图

当用户输入文本时,textview 的高度必须增加到一定高度

我如何使用自动布局来实现这一点,这就是我的自动布局约束的样子

试试这个

/// Orignal Height for Text View
var orignalHeight : CGFloat?

/// Height Constraint of Text View
@IBOutlet weak var descriptionTVHeightConstraint: NSLayoutConstraint!

/// In ViewDidLayoutSubviews Get Height
self.orignalHeight = self.descriptionTextView.frame.size.height

func textViewDidChange(_ textView: UITextView) {
        /// Get Width Which will be always same
        let fixedWidth = textView.frame.size.width

        /// Here we need to get The height as Greatest that we can have or expected
        textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))

        /// Get New Size 
        let newSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))

        /// New Frame
        var newFrame = textView.frame
        newFrame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)

        /// Orignal height is height that is assigned to TextView for first time and 100 is maximum height that textview can increase 
        self.descriptionTVHeightConstraint.constant = min(100,max(Int(newFrame.size.height),Int(self.orignalHeight!))



        bookSessionStruct.sessionTopicDiscussion = textView.text!.trimmed()

    }

UITextViewisScrollEnabled 设置为 false,然后 UITextView 将自动适应它的大小。

并且记住不要为具有常量值的高度锚点添加约束:

textView.snp.makeConstraints{ (maker) in maker.height.greaterThanOrEqualTo(xxx) }

希望对您有所帮助。

UITextView 放入另一个容器视图(此处为红色)并设置容器视图的 constraints 如下图所示。

containerview 中的

UITextViewleading trailing top bottom 约束与 containerview 对齐(红色的)在这里。

之后,您必须使用容器视图的 height 约束和 bottom 约束的引用出口(如下图所示)。

之后将下面显示的代码片段放入 viewDilLoad 方法中...

那就写下这两个方法来控制剩下的事情吧。 Hola!你是冠军!你做到了。

//MARK: TextView delegate

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    if(text == "\n") {
        textView.resignFirstResponder()
        return false
    }
    return true
}


func textViewDidChange(_ textView: UITextView) {


    let fixedWidth = textView.frame.size.width
    textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
    let newSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
    var newFrame = textView.frame
    newFrame = CGRect.init(x: newFrame.origin.x, y: newFrame.origin.y+newFrame.height-newSize.height, width: max(newSize.width, fixedWidth), height: newSize.height)

    let newHeight = newFrame.size.height as CGFloat

    Swift.print("height: %f",newHeight)

    if newHeight > 40 && newHeight <= 105
    {
        chatBoxContainerViewHeightConstraint.constant = newHeight + 16
        UIView.animate(withDuration: 0.3) {
            self.view.layoutIfNeeded()
        }
    }
    else if newHeight <= 40
    {
        chatBoxContainerViewHeightConstraint.constant = 56
        UIView.animate(withDuration: 0.3) {
            self.view.layoutIfNeeded()
        }
    }

}


@objc func keyboardWillChangeFrame(_ notification: NSNotification) {

    if let userInfo = notification.userInfo {

        let duration:TimeInterval = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0
        let animationCurveRawNSN = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber
        let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIViewAnimationOptions.curveEaseInOut.rawValue
        let animationCurve:UIViewAnimationOptions = UIViewAnimationOptions(rawValue: animationCurveRaw)

        let endFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
        let endFrameY = endFrame?.origin.y ?? 0
        let tabbarHeight = self.tabBarController?.tabBar.frame.size.height
        if (endFrameY >= UIScreen.main.bounds.size.height) {
            Swift.print("----< %f",endFrameY)
            self.bottomViewBottomConstraint.constant = 0
        } else  {
            Swift.print("----> %f",endFrameY)
            self.bottomViewBottomConstraint.constant = -((endFrame?.size.height)!-tabbarHeight! )
        }
        UIView.animate(withDuration: duration,
                       delay: TimeInterval(0),
                       options: animationCurve,
                       animations: { self.view.layoutIfNeeded() },
                       completion: nil)
    }
}