patternswiftMinor
Allow UITextView to resize as the user is typing
Viewed 0 times
theuitextviewresizeuserallowtyping
Problem
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;
}
}
}Solution
It can actually be a lot simpler!
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
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:
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
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.
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 :)
}
}Code Snippets
import UIKit
class ViewController: UIViewController {
}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 :)
}
}Context
StackExchange Code Review Q#151454, answer score: 4
Revisions (0)
No revisions yet.