Centre a one line text in a UITextView
I had a problem. First I have set up an UITextView with these parameters:
view.backgroundColor = UIColor.blueColor()
view.text = "An example text"
view.textColor = UIColor.whiteColor()
view.textContainerInset.top = 0
view.textContainerInset.bottom = 0
I wanted to be able to centre the text in the view vertically. This should be easy, one just needs to position the top of the text according to the formula: top = (container.height - content.height) / 2
. However, when you look at the actual look of the UITextView you will see this:
view.font = UIFont.boldSystemFontOfSize(100.0)
view.font = UIFont(name: "DINCondensed-Bold", size: 100.0)
Ouch, there is a semi-randomly placed offset at the top of the text. Turns out the point size of a font is not always the one you have demanded. However it is possible to get the actual height. An UIFont
class provides a bunch of useful metrics:
view.font = UIFont.boldSystemFontOfSize(100.0)
view.font.capHeight // 70.5
view.font.pointSize // 100.0
view.font.ascender // 95.2
view.font.lineHeight // 119.3
view.font = UIFont(name: "DINCondensed-Bold", size: 100.0)
view.font.capHeight // 71.2
view.font.pointSize // 100.0
view.font.ascender // 71.2
view.font.lineHeight // 100.0
On a graph this would look like this:
Finally, the method you can now use is:
extension UITextView {
func centerTextVertically() {
guard let ascender = view.font?.ascender else {
return
}
guard let capHeight = view.font?.capHeight else {
return
}
view.textContainerInset.top = (view.bounds.height - ascender - (ascender - capHeight)) / CGFloat(2.0)
}
}
Note that this will only for one liners and only if you know the height of the UITextView
(i.e.: the height was given to it on creation)