Bigair
Bigair

Reputation: 1592

Adjusting height of UITextView to its text does not work properly

I wrote following code to fit UITextView's height to its text.

The size changes but top margin relative to first line of text differ every other time when I tap enter key on keyboard to add new line.


Setting


import UIKit

class ViewController: UIViewController, UITextViewDelegate {

    lazy var textView: UITextView = {
        let tv = UITextView(frame: CGRectMake(20, 200, (self.view.frame.width - 40), 0) )
        tv.backgroundColor = UIColor.lightGrayColor()
        return tv
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.addSubview( textView )
        
        textView.delegate = self
        let height = self.height(textView)
        let frame = CGRectMake(textView.frame.origin.x, textView.frame.origin.y, textView.frame.width, height)
        textView.frame = frame
    }

    
    func textViewDidChange(textView: UITextView) {
        
        let frame = CGRect(x: textView.frame.origin.x, y: textView.frame.origin.y, width: textView.frame.width, height: height(textView) )
        textView.frame = frame
    }


    func height(textView: UITextView) -> CGFloat {
        let size = CGSizeMake(textView.frame.size.width, CGFloat.max)
        let height = textView.sizeThatFits(size).height
        return height
    }
}

enter image description here enter image description here

I tried few other ways to fit UITextView height but they just acted the same say.

Upvotes: 1

Views: 656

Answers (1)

Joe Smith
Joe Smith

Reputation: 1920

To fix this, subclass UITextView and override setContentOffset to allow scrolling only if the content height is larger than the intrinsic content height. Something like:

override func setContentOffset(_ contentOffset: CGPoint, animated: Bool) {
    let allowScrolling = (contentSize.height > intrinsicContentSize.height)
    if allowScrolling {
        super.setContentOffset(contentOffset, animated: animated)
    }
}

For auto-growing dynamic height text view, the caret moves on starting a new line. At this moment, the size of the text view hasn't grown to the new size yet. The text view tries to make the caret visible by scrolling the text content which is unnecessary.

You may also need to override intrinsicContentSize too.

Upvotes: 1

Related Questions