Recently, I created a repo on Github called ExpandableTextView. The main purpose of this repo is to add a UITextView within a UIToolbar and expand dynamically the height of this UIToolbar depending on the UITextView’s height. The UITextView’s content size may vary depends on the text introduced. To achieve that, I used manual layout, with NSLayoutAnchor and NSLayoutConstraint.
NSLayoutGuide and NSLayoutAnchor were introduced with iOS 9, and the last one is a fluent API to use NSLayoutConstraints. Mention that, whether you understand constraints, they have the same difficulty to create them with code or with Interface Builder.
The next snippet shows, how I add the leading and trailing constraint from the UIToolbar to the superview. And the UIToolbar’s bottom to the superview’s bottom. The heightConstraint was created as a mutable property, we are gonna change this value each time that the keyboard appears (and disappears.)
Tip: First of all, you need to add the subviews before you add any constraint, if not, your app will crash at runtime.
Once the UIToolbar is added and correctly positioned at the leading, trailing and bottom from his superview, you can add the UITextView and a UIButton. Within your UIToolbar subclass:
Then, you apply manual layout to distribute the two UIViews (UITextView and UIButton) inside the UIToolbar.
Here appears something new, you can add a constraint to the margins’ view. The UITextView has been attached to the UIToolbar margins leading. It means that, the constraint has a little gap (standard value: 8) from the UIToolbar leading. Also, the UITextView trailing is attached to UIButton leading (with a constant to separate between them). The Bottom and Top are attached to the UIToolbar.
One of the most important constraints, is the toolbarHeightConstraint, when the UITextView content size change, we need to update this constraint to expand or shrink. Once, we create the NSLayoutConstraint, we need to activate in order to use.
In my UIViewController subclass, there is a delegate method:
This method is called every time the content size of our UITextView did change. Because a new height has to be calculated, to add or remove a new line in our UITextView, To calculate this content size I use the next method:
The next step will be create a new repo with UICollectionViewLayout, simulating a chat conversation.
Tip: example using NSLayoutConstraint:
In the previous NSLayoutConstraints you need to fill a lot of input parameters (a lot of them), and then activate every NSLayoutConstraint. With the next snippet you reduce the amount of code:
As you can see, with NSLayoutAnchor you can add and activate multiple NSLayoutConstraints, with not as many parameters as with NSLayoutConstraint. It’s a quite awesome solution if you had many constraints to add in your view (This fluent API was introduced with iOS 9).