I like the smell of Swift in the morning…

How to get rid of the padding / insets in an UITextView

Posted: | Author: | Filed under: iOS | Tags: | 15 Comments »

Sometimes you want to display some text that contains an email address, an URL, a phone number, an address or a date. Of course you want to make these text parts interactive so that a user can tap on an URL and directly go to the linked webpage, or make a phone call when he taps on a phone number, etc.

Implementing that is really easy. You just use an UITextView and set dataDetectorTypes = .all. And voilá: the UITextView now automatically detects phone numbers, links, calendar events and addresses and makes them tappable. Really nice!

However, there is one caveat: UITextView adds some insets around the text it displays. So if you want to align an UITextView with another UI element (like an UILabel) and you set both elements to the same origin.x, you will see that the text of the UILabel and the text of the UITextView are not aligned. The text of the UITextView is shifted a bit to the right. If you try to align them horizontally you will notice that it is also shifted a bit to the bottom. When you add background color to the UITextView you see that it adds some padding around it’s text. That is nice, if your UITextView has a border or a background color, or you use it to display some editable or scrollable text, but in our case it is not ideal.

Luckily there is a solution for that. UITextView has a property called textContainerInset. The default value for this inset is (top = 8, left = 0, bottom = 8, right = 0). So setting this inset to UIEdgeInsetsZero should get rid of the top and the bottom padding.

textView.textContainerInset = .zero

Works as expected. But there is still some padding to the left and the right of the text. The solution to get rid of that is not as obvious as setting the insets to zero. UITextView uses a NSTextContainer object to define the area in which the text is displayed. And this NSTextContainer object has a property called lineFragmentPadding. This property defines the amount by which the text is inset within line fragment rectangles, or in other words: the left and right padding of the text. The default value for this is 5.0, so setting this to 0 removes the padding.

textView.textContainer.lineFragmentPadding = 0

So, now the text in the UITextView aligns beautifully with the text of the UILabel.