Carl Hung
Carl Hung

Reputation: 555

UITextView resizes the height dynamically with restricting maximum height

I want to make the textview like whatsapp that resizing the textview's height when typing a long string. But once it reaches to the maximum height, the textview's will be remained to the maximum height and the textview becomes scrollable. It is exactly the same as whatsapp's textview when replying message.

I found a way to resize dynamically, but when I set textView.isScrollEnabled = true once it reaches to the maximum height, the textview will shrink but be scrollable.

How can I make the textview exactly like whatsapp's 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
}

enter image description here

Upvotes: 2

Views: 2638

Answers (2)

Agent Smith
Agent Smith

Reputation: 2923

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 is an outlet for textview's height constraint.

As the text changes in textview you can calculate the current line of text you are working on and update its constraint to default (56 in my case) if currentLine is 0 else set it to textView.contentSize.height.

Hope it helps

Upvotes: 1

dahiya_boy
dahiya_boy

Reputation: 9503

 var textViewContentSize = textView.sizeThatFits(textView.bounds.size)

This will returns you the minimum size required of the UITextView to show all the contents in it.

and for restriction use below code

if textViewContentSize.height > 200{
   textViewContentSize = CGSize(width: textViewContentSize.height, height: 200)
}

So now your textview frame is as below,

textView.frame = CGRect(origin: textView.frame.origin, size: textViewContentSize)

Hope it helps you.

Upvotes: 0

Related Questions