'Swift 3: UITextView - Dynanmic height - Programmatically
I have a keyboardContainer class (Subclass of UIView / created programmatically so no storyboard) including a UITextView for the user to type messages in. It is used within a Chat log class and set as the inputAccessoryView. I want to dynamically change the height of it when the user is typing.
I searched for answers and found some. However, I didn't get most of them as they didn't work for me.
What do I have to implement to get the effect I want to have?
Thank´s for your help!
EDIT:
First of all thank you for your help!
However, I´m pretty new to coding so I could not solve the issue. I guess it has something to do with the way I created my keyboardContainer class and its constraints...
Here is the relevant code from within my keyboard container class:
let textField:UITextView = {
let view = UITextView()
view.translatesAutoresizingMaskIntoConstraints = false
view.layer.cornerRadius = 15
view.layer.masksToBounds = true
view.font = UIFont.systemFont(ofSize: 15)
view.backgroundColor = .white
return view
}()
overried init(frame: CGRect){
super.init(frame: frame)
addSubview(textField)
textField.leftAnchor.constraint(equalTo: leftButton, constant: 5).isActive = true
textField.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
textFieldHeightAnchor = textField.heightAnchor.constraint(equalTo: heightAnchor, constant: -10)
textFieldHeightAnchor.isActive = true
textFieldRightAnchor = textField.rightAnchor.constraint(equalTo: rightAnchor, constant: -85)
textFieldRightAnchor.isActive = true
}
Inside my ChatLog I´m using this:
lazy var keyboard: KeyboardContainer = {
let key = KeyboardContainer()
key.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: 45)
key.sendButton.addTarget(self, action: #selector(handleSend), for: .touchUpInside)
return key
}()
override var inputAccessoryView: UIView?{
get{
return keyboard
}
}
What do I need to change ? I guess the constraints?
Solution 1:[1]
You can make your textView conform to the UITextViewDelegate and then resize it to it's contentSize.
Make your view controller conform to the delegate
class ViewController: UIViewController, **UITextViewDelegate** { ...
After that
yourTextView.delegate = self // put that in viewDidLoad()
Then you can implement the textViewDidChange method. That means, every time you enter something into the keyboard, this function is called.
func textViewDidChange(_ textView: UITextView) {
if textView == youTextView {
let currentHeight = textView.frame.size.height
textView.frame.size.height = 0 // you have to do that because if not it's not working with the proper content size
textView.frame.size = textView.contentSize // here you detext your textView's content size and make it resize.
let newHeight = textView.frame.size.height
let heightDifference = newHeight - currentHeight // get the height difference from before and after editing
yourContainerView.frame.size.height += heightDifference
}
}
Solution 2:[2]
Just disable the scrolling. Don't set any other constraints. This might help you with this.
In your viewDidLoad method,
YourTextView.translatesAutoresizingMaskIntoConstraints = true
YourTextView.sizeToFit()
YourTextView.isScrollEnabled = false
YourTextView.delegate = self
YourTextView.isEditable = true
Then use UITextViewDelegate and,
func textViewDidChange(_ textView: UITextView) {
MyTextView.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: 100)
MyTextView.translatesAutoresizingMaskIntoConstraints = true
MyTextView.sizeToFit()
MyTextView.isScrollEnabled = false
}
Solution 3:[3]
If you are looking for UITextView
like any message app.
No need to deal with code you can manage it using constraints only.
Seems a better way to do this using constraints rather than deal with more coding.
Here is the step by step explanation of this.
Step : 1
- Arrange
UItextView
andUIBUtton
inside oneUIView
and give height constraint toUIView
with low priority.
Step : 2
Step : 3
Now you just have to deal with contentSize
and isScrollEnabled
as below snippet.
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool{
if (textView.contentSize.height < 150){
textView.isScrollEnabled = false
}
else{
textView.isScrollEnabled = true
}
return true
}
Hope this help you!!
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Matt Harris |
Solution 2 | |
Solution 3 |