如何获取UILabel实际显示的截断后字符串?
获取UILabel实际显示的截断字符串
可以获取到UILabel实际显示的截断后字符串,包括中文、表情等复杂字符,核心思路是利用TextKit组件模拟UILabel的文本布局逻辑,准确计算出指定行数下能容纳的文本范围,再处理系统自动添加的省略号。
实现代码(Swift)
给UILabel添加扩展方法,直接获取显示内容:
extension UILabel { func getDisplayedTruncatedText() -> String? { guard let attrText = attributedText else { return text } let textStorage = NSTextStorage(attributedString: attrText) let layoutManager = NSLayoutManager() textStorage.addLayoutManager(layoutManager) // 复制当前Label的文本容器配置,保证布局逻辑一致 let textContainer = NSTextContainer(size: bounds.size) textContainer.lineFragmentPadding = lineFragmentPadding textContainer.maximumNumberOfLines = numberOfLines textContainer.lineBreakMode = lineBreakMode layoutManager.addTextContainer(textContainer) // 计算容器能容纳的文本范围 let displayRange = layoutManager.glyphRange(for: textContainer) var displayedAttrText = attrText.attributedSubstring(from: displayRange) // 判断是否需要补充省略号(原文本超出显示范围时) if displayRange.length < attrText.length { // 取原文本末尾的属性作为省略号的样式,保证视觉统一 let ellipsisAttrs = attrText.attributes(at: min(displayRange.length, attrText.length - 1), effectiveRange: nil) let ellipsis = NSAttributedString(string: "...", attributes: ellipsisAttrs) // 替换末尾对应长度的内容为省略号,避免截断在字符中间 let replaceRange = NSRange(location: max(0, displayRange.length - ellipsis.length), length: ellipsis.length) displayedAttrText = displayedAttrText.replacingCharacters(in: replaceRange, with: ellipsis) } return displayedAttrText.string } }
使用注意事项
- 必须在UILabel完成布局后调用(比如
viewDidLayoutSubviews方法内,或手动调用sizeToFit()之后),否则容器尺寸不准确会导致计算偏差。 - 代码适配了默认的尾部截断模式,若使用其他截断模式(如头部截断),需要调整省略号的添加位置逻辑。
内容的提问来源于stack exchange,提问作者Mix
相关产品推荐
相关产品推荐

