3
\$\begingroup\$

I want to be sure that in terms of auto-layout or just following the proper methods of doing the following is acceptable. I am not sure if there will be an constraint issues or efficiency problems that could slow down my app. It is working so far, I am in the process of trying to animate it as it resizes.

import UIKit
class PickUpViewController: UIViewController, UITextViewDelegate {
 @IBOutlet weak var addressTextVIew: TextViewAutoHeight!
 override func viewDidLoad() {
 super.viewDidLoad()
 addressTextVIew.delegate = self
 }
 func textViewDidChange(_ textView: UITextView) {
 if textView.contentSize.height > textView.frame.size.height {
 let fixedWidth = textView.frame.size.width
 textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
 var newFrame = textView.frame
 let newSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
 newFrame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)
 textView.frame = newFrame;
 }
 }
}
200_success
145k22 gold badges190 silver badges478 bronze badges
asked Jan 2, 2017 at 10:10
\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

It can actually be a lot simpler!

UITextView is a UIScrollView where by default the contentSize updates to fit whatever text is in the current view.

Assuming that you have constraints set up (e.g. pinning left, top, and right anchors so that the height is free to grow) then it's as simple as overriding the default value of isScrollEnabled and setting it to false.

You could do that either in your storyboard, or in your text view subclass.

I would suggest moving any logic you have around animating size of the text view out of the view controller and bundle it into your text view subclass.

Assuming that your constraints are set up in the storyboard, your view controller (at this point) doesn't need to have anything:

import UIKit 
class ViewController: UIViewController {
}

Your text view subclass should have everything it needs to do to animate it's height change, and keeping the code there will make your view controllers more lightweight, and your TextViewAutoHeight more reusable in different scenarios.

Your current code doesn't actually animate the height so it's off-topic for /CodeReview, so I suggest searching stack overflow for questions around "UIView animate with duration", and perhaps reposting here when you have working code ready for review.

import UIKit
class TextViewAutoHeight: UITextView {
 required init?(coder aDecoder: NSCoder) {
 super.init(coder: aDecoder)
 isScrollEnabled = false
 NotificationCenter.default.addObserver(self, selector: #selector(updateHeight), name: NSNotification.Name.UITextViewTextDidChange, object: nil)
 }
 func updateHeight() {
 // trigger your animation here
 /*
 var newFrame = frame
 let fixedWidth = frame.size.width
 let newSize = sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
 newFrame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)
 self.frame = newFrame
 */
 // suggest searching stackoverflow for "uiview animatewithduration" for frame-based animation
 // or "animate change in intrinisic size" to learn about a more elgant solution :)
 }
}
answered Jan 3, 2017 at 16:22
\$\endgroup\$
1
  • \$\begingroup\$ why is body of updateheight() commented? \$\endgroup\$ Commented Aug 30, 2018 at 7:29

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.