How to lose margin/padding in UITextView?
I have a UITextView
in my iOS Application, which displays a large amount of text. I am then paging this text by using the offset margin parameter of the UITextView
. My problem is that the padding of the UITextView
is confusing my calculations as it seems to be different depending on the font size and typeface that I use.
Therefore, I pose the question: Is it possible to remove the padding surrounding the content of the UITextView
?
Look forward to hearing your responses!
For 2018
It is one of the silliest bugs in iOS.
UITextViewFixed
is a usually a reasonable solution:
@IBDesignable class UITextViewFixed: UITextView {
override func layoutSubviews() {
super.layoutSubviews()
setup()
}
func setup() {
textContainerInset = UIEdgeInsets.zero
textContainer.lineFragmentPadding = 0
}
}
Don't forget to turn off scrollEnabled in the Inspector!
That solution does work properly in storyboard, as well as at runtime.
That's it, you're done.
In general, that should be all you need in most cases .
(Even if you are changing the height of the text view on the fly - for example as the user types - this usually does all you need.)
Here is the broken UITextView from Apple...
In almost all cases, UITextViewFixed
is an acceptable fix:
(Yellow added for clarity.) Note that of course you must
turn off scrollEnabled in the Inspector!
Don't forget to turn off scrollEnabled! :)
Some further issues
(1) In some cases - for example, sometimes when using autolayout with flexible cell height table views which are changing height on the fly - Apple does the most infuriating thing in the world: they add extra space at the bottom . It would have to be one of the craziest, most infuriating things in iOS. Here is a "quick fix" to add which sometimes helps with that madness.
...
textContainerInset = UIEdgeInsets.zero
textContainer.lineFragmentPadding = 0
// this is not ideal, but you can sometimes use this
// to fix the "space at bottom" insanity
var b = bounds
let h = sizeThatFits(CGSize(
width: bounds.size.width,
height: CGFloat.greatestFiniteMagnitude)
).height
b.size.height = h
bounds = b
...
(2) Sometimes, to fix yet another subtle Apple mess-up, you have to add this:
override func setContentOffset(_ contentOffset: CGPoint, animated: Bool) {
super.setContentOffset(contentOffset, animated: false)
}
(3) Arguably, we should be adding :
contentInset = UIEdgeInsets.zero
just after .lineFragmentPadding = 0
. However ... it doesn't work in current iOS! It may be necessary to add that in future OS versions.
The fact that UITextView
, of all things, is totally broken in iOS is just one of the weirdest things in all of mobile computing.
Finally, here's a somewhat similar tip for Text Field : https://stackoverflow.com/a/43099816/294884
For iOS 7.0, I've found that the contentInset trick no longer works. This is the code I used to get rid of the margin/padding in iOS 7.
This brings the left edge of the text to the left edge of the container:
textView.textContainer.lineFragmentPadding = 0
This causes the top of the text to align with the top of the container
textView.textContainerInset = .zero
Both Lines are needed to completely remove the margin/padding.
This workaround was written in 2009 when IOS 3.0 was released. It no longer applies.
I ran into the exact same problem, in the end I had to wind up using
nameField.contentInset = UIEdgeInsetsMake(-4,-8,0,0);
where nameField is a UITextView
. The font I happened to be using was Helvetica 16 point. Its only a custom solution for the particular field size I was drawing. This makes the left offset flush with the left side, and the top offset where I want it for the box its draw in.
In addition, this only seems to apply to UITextViews
where you are using the default aligment, ie.
nameField.textAlignment = NSTextAlignmentLeft;
Align to the right for example and the UIEdgeInsetsMake
seems to have no impact on the right edge at all.
At very least, using the .contentInset property allows you to place your fields with the "correct" positions, and accommodate the deviations without offsetting your UITextViews
.