Midhun Narayan
Midhun Narayan

Reputation: 879

how to set textview height dynamically using autolayout

Need to setup a textview which will have 30 as its initial height enter image description here like this

while user entering the text the textview height have to be increased till certain height

enter image description here

How can i achieve this using autolayout and this is how my autolayout constraints look like enter image description here

Upvotes: 0

Views: 1836

Answers (3)

Koustov Basu
Koustov Basu

Reputation: 82

enter image description here

Put the UITextView within another container view (Colour red here)and set the constraints of the containerview like the below mentioned image.

enter image description here

UITextView within the containerview will have leading trailing top bottom constraint aligned to the containerview (The red one) here.

after that you have to take the referencing outlet of the height constraint & bottom constraint of the containerview (Image provided below).

enter image description here

After that put the piece of code shown below in viewDilLoad method...

enter image description here

Then just write down the two method to control the rest of the things. And Hola ! you are a champion ! You have made it.

//MARK: TextView delegate

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    if(text == "\n") {
        textView.resignFirstResponder()
        return false
    }
    return true
}


func textViewDidChange(_ textView: UITextView) {


    let fixedWidth = textView.frame.size.width
    textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
    let newSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
    var newFrame = textView.frame
    newFrame = CGRect.init(x: newFrame.origin.x, y: newFrame.origin.y+newFrame.height-newSize.height, width: max(newSize.width, fixedWidth), height: newSize.height)

    let newHeight = newFrame.size.height as CGFloat

    Swift.print("height: %f",newHeight)

    if newHeight > 40 && newHeight <= 105
    {
        chatBoxContainerViewHeightConstraint.constant = newHeight + 16
        UIView.animate(withDuration: 0.3) {
            self.view.layoutIfNeeded()
        }
    }
    else if newHeight <= 40
    {
        chatBoxContainerViewHeightConstraint.constant = 56
        UIView.animate(withDuration: 0.3) {
            self.view.layoutIfNeeded()
        }
    }

}


@objc func keyboardWillChangeFrame(_ notification: NSNotification) {

    if let userInfo = notification.userInfo {

        let duration:TimeInterval = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0
        let animationCurveRawNSN = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber
        let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIViewAnimationOptions.curveEaseInOut.rawValue
        let animationCurve:UIViewAnimationOptions = UIViewAnimationOptions(rawValue: animationCurveRaw)

        let endFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
        let endFrameY = endFrame?.origin.y ?? 0
        let tabbarHeight = self.tabBarController?.tabBar.frame.size.height
        if (endFrameY >= UIScreen.main.bounds.size.height) {
            Swift.print("----< %f",endFrameY)
            self.bottomViewBottomConstraint.constant = 0
        } else  {
            Swift.print("----> %f",endFrameY)
            self.bottomViewBottomConstraint.constant = -((endFrame?.size.height)!-tabbarHeight! )
        }
        UIView.animate(withDuration: duration,
                       delay: TimeInterval(0),
                       options: animationCurve,
                       animations: { self.view.layoutIfNeeded() },
                       completion: nil)
    }
}

Upvotes: 0

likeSo
likeSo

Reputation: 41

Set UITextView's isScrollEnabled to false, then UITextView will fit it's size automatically.

And Remember do not add constraints for height anchor with a constant value:

textView.snp.makeConstraints{ (maker) in maker.height.greaterThanOrEqualTo(xxx) }

Hope that helpful.

Upvotes: 0

iOS Geek
iOS Geek

Reputation: 4855

Try This

/// Orignal Height for Text View
var orignalHeight : CGFloat?

/// Height Constraint of Text View
@IBOutlet weak var descriptionTVHeightConstraint: NSLayoutConstraint!

/// In ViewDidLayoutSubviews Get Height
self.orignalHeight = self.descriptionTextView.frame.size.height

func textViewDidChange(_ textView: UITextView) {
        /// Get Width Which will be always same
        let fixedWidth = textView.frame.size.width

        /// Here we need to get The height as Greatest that we can have or expected
        textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))

        /// Get New Size 
        let newSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))

        /// New Frame
        var newFrame = textView.frame
        newFrame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)

        /// Orignal height is height that is assigned to TextView for first time and 100 is maximum height that textview can increase 
        self.descriptionTVHeightConstraint.constant = min(100,max(Int(newFrame.size.height),Int(self.orignalHeight!))



        bookSessionStruct.sessionTopicDiscussion = textView.text!.trimmed()

    }

Upvotes: 3

Related Questions