I have a multi-line UILabel
(numberOfLines
= 0). It's width can change at runtime, and sometimes this leads to truncation and/or re-wrapping. Some examples illustrate this best:
Example 1: the reduction in width leads to a different line break point
Example 2: the reduction in width leads to truncation
Example 3: the reduction in width leads to both truncation and a different line break position
Example 4: the reduction in width does not have any effect on truncation or line break position
Since this change in formatting can be quite jarring, I intend to mask it behind some animation (probably a fade in/fade out). However, the first hurdle is identifying when I need to do this. I don't want to apply the animation whenever the label re-sizes - only when it will cause a change in either truncation or line break positions.
How might I test this? The test should return YES for example 1, 2, and 3, but NO for example 4.
Note: the resizing will never alter the number of lines in my example.
Note 2: if anyone has some better tags related to text formatting I'd love to know them - feel free to edit.
Note 3: if you are interested in seeing this behavior accomplished, try Apple's mail.app on the iPhone. When viewing the inbox, swipe an email and watch the summary line fade-in/out as it re-wraps and/or truncates (but not when it doesn't need to).
With a UILabel you can check for truncation by calculating the size of the text within the label and comparing that with the bounds of the label itself. If the text extends beyond the bounds then it's being displayed as truncated.
You are dividing width by height and if it is bigger than number of line (which might very well be 0) you are saying label is truncated.
To add line breaks in the text we'll use \n character in the string we want to assign to the label.
Swift 3 solution
You can count the number of lines after assigning the string and compare to the max number of lines of the label.
import Foundation
import UIKit
extension UILabel {
func countLabelLines() -> Int {
// Call self.layoutIfNeeded() if your view is uses auto layout
let myText = self.text! as NSString
let attributes = [NSFontAttributeName : self.font]
let labelSize = myText.boundingRect(with: CGSize(width: self.bounds.width, height: CGFloat.greatestFiniteMagnitude), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: attributes, context: nil)
return Int(ceil(CGFloat(labelSize.height) / self.font.lineHeight))
}
func isTruncated() -> Bool {
if (self.countLabelLines() > self.numberOfLines) {
return true
}
return false
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With