Answer for 2017...
c = CGSize(width: yourWidth, height: CGFloat.greatestFiniteMagnitude)
result = sizeThatFits(c).height
So...
let t = .... your UITextView
let w = .... your known width of the item
let trueHeight = t.sizeThatFits(
CGSize(width: t, height: CGFloat.greatestFiniteMagnitude)).height
That's it.
Very often, you want to know the difference in height compared to a "normal" one-line entry.
This comes up in particular if you are making some sort of cells that have nothing to do with UTableView (say, some sort of custom stack view). You have to set the height manually at some point. On your storyboard, build it as you wish, using a sample text of any short string (eg, "A") which of course will have only one line in any normal situation. Then you do something like this...
func setTextWithSizeCorrection() { // an affaire iOS
let t = .... your UITextView
let w = .... your known width of the item
let oneLineExample = "A"
let actualText = yourDataSource[row].description.whatever
// get the height as if with only one line...
experimental.text = oneLineExample
let oneLineHeight = t.sizeThatFits(
CGSize(width: w, height: CGFloat.greatestFiniteMagnitude)).height
// get the height with the actual long text...
// (note that usually, you do not want a one-line minimum)
experimental.text = (actualText == "") ? oneLineExample : actualText
let neededHeight = t.sizeThatFits(
CGSize(width: w, height: CGFloat.greatestFiniteMagnitude)).height
experimental.text = actualText
let delta = neededHeight - oneLineHeight
set the height of your cell, or whatever it is(standardHeight + delta)
}
Final point: one of the really stupid things in iOS is that UITextView has a bizarre sort of margin inside it. This means you can't just swap between UITextViews and labels; and it causes many other problems. Apple haven't fixed this issue as of writing. To fix the problem is difficult: the following approach is usually OK:
@IBDesignable class UITextViewFixed: UITextView {
override func layoutSubviews() {
super.layoutSubviews()
setup()
}
func setup() {
textContainerInset = UIEdgeInsets.zero;
textContainer.lineFragmentPadding = 0;
}
}
Broken, unusable UITextView from Apple...
UITextViewFixed
which is, in most cases, an acceptable fix:
(Yellow added for clarity.)