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;
}
}
}
1 Answer 1
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 :)
}
}
-
\$\begingroup\$ why is body of updateheight() commented? \$\endgroup\$nikhil nangia– nikhil nangia2018年08月30日 07:29:26 +00:00Commented Aug 30, 2018 at 7:29