Given is a (html) String with x-number of characters. The String will get formatted into an attributed String. Then displayed in a UILabel
.
The UILabel
has a height of >= 25
and <= 50
to limit the number of lines to 2.
Since the String has characters not visible in the formatted attributed String, like <b> / <i>
, the best approach would be to limit the character count of the attributed String.
UILabel
property .lineBreakMode = .byTruncatingTail
causes words to get cut.
The goal, in case the character count would exceed the limit of space in the UILabel
, is to cut between words. Desired maxCharacterCount = 50
. Determine the last space
before maxCharacterCount
. Cut the String and append ...
as last characters of the UILabel
.
What's the best approach to limit the characters? Help is very appreciate.
Start with the full string and the known two-line height of the label and its known width, and keep cutting words off the end of the string until, at that width, the string's height is less than the label's height. Then cut one more word off the end for good measure, append the ellipsis, and put the resulting string into the label.
In that way, I got this:
Notice that the word after "time" never starts; we stop at a precise word-end with the inserted ellipsis. Here's how I did that:
lab.numberOfLines = 2
let s = "Little poltergeists make up the principle form of material " +
"manifestation. Now is the time for all good men to come to the " +
"aid of the country."
let atts = [NSFontAttributeName: UIFont(name: "Georgia", size: 18)!]
let arr = s.components(separatedBy: " ")
for max in (1..<arr.count).reversed() {
let s = arr[0..<max].joined(separator: " ")
let attrib = NSMutableAttributedString(string: s, attributes: atts)
let height = attrib.boundingRect(with: CGSize(width:lab.bounds.width,
height:10000),
options: [.usesLineFragmentOrigin],
context: nil).height
if height < lab.bounds.height {
let s = arr[0..<max-1].joined(separator: " ") + "…"
let attrib = NSMutableAttributedString(string: s, attributes: atts)
lab.attributedText = attrib
break
}
}
It is of course possible to be much more sophisticated about what constitutes a "word" and in the conditions for measurement, but the above demonstrates the general common technique for this sort of thing and should suffice to get you started.
try this:
import UIKit
class ViewController: UIViewController {
var str = "Hello, playground"
var thisInt = 10
@IBOutlet weak var lbl: UILabel!
var lblWidth : CGFloat = 0.0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
lblWidth = lbl.bounds.width
while str.characters.count <= thisInt - 3 {
str.remove(at: str.index(before: str.endIndex))
str.append("...")
}
lbl.text = str
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
string width calculation link
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