'How to change truncate characters in UILabel?
When the text of a UILabel gets truncated there are 3 dots inserted by default.
Is it possible to change these characters or disable them?
Solution 1:[1]
Look at -[UILabel setLineBreakMode:] and UILineBreakModeCharacterWrap. The default value of -[UILabel lineBreakMode] is UILineBreakModeTailTruncation, which causes the ellipsis at the end.
Solution 2:[2]
As Javanator said you would have to do your own truncation. You shuld use the
sizeWithFont:forWidth:lineBreakMode: message on the UIKit additions to NSString class to get the width of a string with a certain font. This will handle all types of fonts.
Solution 3:[3]
You can also set
[lbl setAdjustsFontSizeToFitWidth:YES];
With this there will be no need of truncating text and you can display the complete text on your label.
Solution 4:[4]
I would like to provide a more Swifty version of what Fonix provided earlier and using Swift 5 syntax. Also I decided to write the functions as an extension of UILabel.
extension UILabel {
func replaceEllipsis(withString replacement: String, andMaximumWidth width: CGFloat = 0) -> Bool {
if let labelText = self.text, let font = self.font {
let origSize = self.frame
var useWidth = width
if width <= 0 {
useWidth = origSize.width // use label width by default if width <= 0
}
self.sizeToFit()
let labelSize = labelText.size(withAttributes: [NSAttributedString.Key.font: font])
if labelSize.width > useWidth {
let truncateWidth = useWidth
let subLength = labelText.count
var newText = String(labelText[..<labelText.index(labelText.endIndex, offsetBy: -1)])
newText = String(newText[..<newText.index(labelText.startIndex, offsetBy: getTruncatedStringPoint(splitPoint: subLength,
original: labelText,
truncatedWidth: truncateWidth,
font: font,
length: subLength))])
newText = String.localizedStringWithFormat("%@%@", newText, replacement)
var count = 0
while newText.size(withAttributes: [NSAttributedString.Key.font: font]).width > useWidth {
count += 1
newText = String(labelText[..<labelText.index(labelText.endIndex, offsetBy: -(1 + count))])
newText = newText.trimmingCharacters(in: NSCharacterSet.whitespaces)
newText = String.localizedStringWithFormat("%@%@", newText, replacement)
}
self.text = newText
self.frame = origSize
return true
} else {
self.frame = origSize
return false
}
} else {
return false
}
}
private func getTruncatedStringPoint(splitPoint: Int, original: String, truncatedWidth: CGFloat, font: UIFont, length: Int) -> Int {
let index = original.index(original.startIndex, offsetBy: splitPoint)
let splitLeft = String(original[..<index])
let subLength = length / 2
if subLength <= 0 {
return splitPoint
}
let width = splitLeft.size(withAttributes: [NSAttributedString.Key.font: font]).width
if width > truncatedWidth {
return getTruncatedStringPoint(splitPoint: splitPoint - subLength, original: original, truncatedWidth: truncatedWidth, font: font, length: subLength)
} else if width < truncatedWidth {
return getTruncatedStringPoint(splitPoint: splitPoint + subLength, original: original, truncatedWidth: truncatedWidth, font: font, length: subLength)
} else {
return splitPoint
}
}
}
It'll be used as follows:
<UILabel>.replaceEllipsis(withString: " ...Read More") // if you want to use the label width
Also you can pass a custom width as well if you need to. I opted for the default width in the above example.
For references on what I used in my refactor, the below StackOverflow links were helpful:
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Heath Borders |
| Solution 2 | |
| Solution 3 | Girish |
| Solution 4 | David Shi |
