Ios UITextView通过限制最大高度动态调整高度大小

Ios UITextView通过限制最大高度动态调整高度大小,ios,swift,autolayout,uitextview,Ios,Swift,Autolayout,Uitextview,我想让textview像whatsapp一样,在键入长字符串时调整textview的高度。但一旦达到最大高度,textview将保持最大高度,textview将可滚动。它与回复消息时whatsapp的文本视图完全相同 我找到了一种动态调整大小的方法,但是当我设置textView.isScrollEnabled=true达到最大高度时,textView将缩小但可以滚动 如何使textview与whatsapp的textview完全相同 override func viewDidLoad() {

我想让textview像
whatsapp
一样,在键入长字符串时调整textview的高度。但一旦达到最大高度,textview将保持最大高度,textview将可滚动。它与回复消息时whatsapp的文本视图完全相同

我找到了一种动态调整大小的方法,但是当我设置
textView.isScrollEnabled=true
达到最大高度时,textView将缩小但可以滚动

如何使textview与
whatsapp
的textview完全相同

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(updateHeight), name: NSNotification.Name.UITextViewTextDidChange, object: nil)
    textView.isScrollEnabled = false
    // ...
}

func updateHeight() {
    var contentSize = textView.sizeThatFits(textView.bounds.size)
    contentSize.width = UIScreen.main.bounds.width
    if contentSize.height > UIScreen.main.bounds.height / 5{
        textView.isScrollEnabled = true
        contentSize.height = UIScreen.main.bounds.height / 5
    } else {
        textView.isScrollEnabled = false
    }
    textView.frame.size = contentSize
}

这将返回显示其中所有内容所需的
UITextView
的最小大小

以下代码仅供限制使用

if textViewContentSize.height > 200{
   textViewContentSize = CGSize(width: textViewContentSize.height, height: 200)
}
现在您的
textview
框架如下所示

textView.frame = CGRect(origin: textView.frame.origin, size: textViewContentSize)
希望对你有帮助

extension ViewController : UITextViewDelegate{

  func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool{

    let cursorPosition = self.textView.caretRect(for: self.tvChat.selectedTextRange!.start).origin
    let currentLine = Int(cursorPosition.y / self.tvChat.font!.lineHeight)

     UIView.animate(withDuration: 0.3) {
        if currentLine == 0 {
            self.constraintHeightTextView.constant = 56
        }else {
            self.constraintHeightTextView.constant = self.textView.contentSize.height + 8 // Padding
        }
    }
    self.textView.layoutIfNeeded()
    self.view.updateConstraints()
  }
}
self.constraintHeightTextView是textview高度约束的一个出口

当文本在textview中更改时,您可以计算当前正在处理的文本行,并将其约束更新为默认值(在我的情况下为56),如果currentLine为0,则将其设置为textview.contentSize.height


希望它能有所帮助

我认为问题在于textView.isScrolEnabled=true,这将使整个textView缩小到一行的高度。但当我插入print(“Height:(contentSize.Height)”)时,它会打印出文本视图的高度(取决于行数)。这将返回一个固定大小的文本视图。不动态更改高度。@返回textView中内容的大小。如果将
textView.isScrollEnabled=false设置为
textView.height
,那么请考虑何时限制
textView.height
。它不限制您设置高度。好的,如果textView.IsCrollenabled=false,我的代码将根据字符串的长度动态调整大小。但如果我将其设置为true,textview将返回到一行的高度。你知道我的意思吗?@CarlHung在你的文本视图中写50行,告诉我你的输出界面是什么。显然,textView的大小为50行,而您的tableView变小了。您使用自动布局吗?如果是,您提供了哪些约束?textView.top=tableView.buttomi如果您提供了高度约束,则为其设置一个出口,并更改其常数,而不是每次设置帧。这将起作用。但tableView没有固定高度。如果textView.IsCrollenabled=false,一切正常。我使用您使用textview高度约束的解决方案,并将这段代码放在我的updateHeight()中,它工作正常。谢谢。@CarlHung您能添加完整的代码吗?
extension ViewController : UITextViewDelegate{

  func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool{

    let cursorPosition = self.textView.caretRect(for: self.tvChat.selectedTextRange!.start).origin
    let currentLine = Int(cursorPosition.y / self.tvChat.font!.lineHeight)

     UIView.animate(withDuration: 0.3) {
        if currentLine == 0 {
            self.constraintHeightTextView.constant = 56
        }else {
            self.constraintHeightTextView.constant = self.textView.contentSize.height + 8 // Padding
        }
    }
    self.textView.layoutIfNeeded()
    self.view.updateConstraints()
  }
}