I have a UITableView with variably sized cells. The height is based on a block of text that I need to display so I need to measure the text.
I'm just using some Lorem Ipsum text:
"Nullam est elit, rutrum volutpat scelerisque eu, tincidunt ut magna. Quisque sit amet odio quis eros lobortis cursus. Phasellus mauris augue, mattis a posuere sit amet, dictum sit amet ipsum. Praesent velit sapien, tristique ut pellentesque eget, venenatis in est. Curabitur accumsan lacus nec ultricies finibus. In commodo, turpis at auctor lobortis, augue ipsum tincidunt lorem, vitae fringilla libero magna eget tortor. Sed et ultrices odio, et viverra diam. Mauris semper non lorem varius sollicitudin. Maecenas nec dui lectus. In hac habitasse platea dictumst. Quisque sapien ex, pretium id vehicula eget, tempus at nisl. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aliquam vel sollicitudin velit, efficitur accumsan sem. Quisque id urna blandit, cursus justo sed, aliquet velit. Nullam id ipsum pellentesque, gravida nulla ut, tempor libero."
When I call ceil(text.height())
it returns 386.0
tall, but when I put that text into the UITextView and print out the content size of the UITextView it says the content is 422.0
tall. (i.e. my text is getting cut off because the UITextView isn't tall enough to display everything.)
Why is there a difference?
I'm using the following String extension to calculate the height of the text:
extension String {
func height(withConstrainedWidth width: CGFloat, font: UIFont) -> CGFloat {
let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)
let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil)
return boundingBox.height
}
}
Then in tableView(heightForRowAt:)
I calculate the height of the text and add it to the space above and below the textview to get the full cell height (this was more elegant before I started debugging this):
let textviewWidth = self.view.frame.size.width-CGFloat(32)
let spaceAboveTextView = CGFloat(45)
let spaceBelowTextView = CGFloat(16)
let textHeight = ceil(text.height(withConstrainedWidth: textviewWidth, font: UIFont.systemFont(ofSize: 17.0)))
let height = spaceAboveTextView + textHeight + spaceBelowTextView
I've verified that the UITextView is using the System Font of size 17, which matches with my code above.
I've verified the frame of the UITextView (after being displayed) is (16.0, 45.0, 382.0, 385.6667)
so the spaceAboveTextView=45
is accurate and the width=382
is accurate. I've also checked the constraints on the UITextView and it has a bottom constraint of 8pt to the margin and the margin is 8pt for a total of 16pt in the spaceBelowTextView
as well.
So, what am I doing wrong?