You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中能否调整UILabel省略号的垂直位置?

实现垂直底部的省略号(替代UILabel的byTruncatingTail)

原生UILabel的.byTruncatingTail换行模式无法直接将省略号调整到垂直底部——系统默认会让省略号和最后一行文本保持对齐(你的文本设置了居中,所以省略号会落在垂直中间位置)。要实现省略号在底部的效果,需要自定义处理逻辑,以下是可行的实现方案:

实现思路

  1. 先判断完整文本是否超出label的高度限制
  2. 若需要截断,逐步截取文本内容,确保加上省略号后的整体高度不超过label高度
  3. 调整文本的垂直对齐方式,让最终内容(含省略号)贴紧label底部

示例代码

class BottomTruncationLabel: UILabel {
    override var text: String? {
        didSet {
            updateTruncatedText()
        }
    }
    
    override var attributedText: NSAttributedString? {
        didSet {
            updateTruncatedText()
        }
    }
    
    private func updateTruncatedText() {
        guard let originalContent = self.attributedText ?? text.map({ NSAttributedString(string: $0) }) else { return }
        
        let maxLabelSize = CGSize(width: bounds.width, height: bounds.height)
        let fullTextHeight = originalContent.boundingRect(with: maxLabelSize, options: [.usesLineFragmentOrigin, .usesFontLeading], context: nil).height
        
        // 文本未超出限制,直接显示
        if fullTextHeight <= maxLabelSize.height {
            super.attributedText = originalContent
            return
        }
        
        // 开始处理截断逻辑
        let mutableContent = NSMutableAttributedString(attributedString: originalContent)
        let ellipsisAttrs = mutableContent.attributes(at: 0, effectiveRange: nil)
        let ellipsis = NSAttributedString(string: "...", attributes: ellipsisAttrs)
        let ellipsisWidth = ellipsis.boundingRect(with: CGSize(width: CGFloat.greatestFiniteMagnitude, height: maxLabelSize.height), options: .usesLineFragmentOrigin, context: nil).width
        
        var truncatedLength = mutableContent.length
        while truncatedLength > 0 {
            truncatedLength -= 1
            let truncatedSubstring = mutableContent.attributedSubstring(from: NSRange(location: 0, length: truncatedLength))
            let combinedContent = NSMutableAttributedString(attributedString: truncatedSubstring)
            combinedContent.append(ellipsis)
            
            let combinedHeight = combinedContent.boundingRect(with: maxLabelSize, options: [.usesLineFragmentOrigin, .usesFontLeading], context: nil).height
            if combinedHeight <= maxLabelSize.height {
                // 调整段落样式,确保文本垂直底部对齐
                let paragraphStyle = NSMutableParagraphStyle()
                paragraphStyle.lineSpacing = 2
                paragraphStyle.alignment = .center
                paragraphStyle.lineBreakMode = .byClipping
                combinedContent.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: combinedContent.length))
                
                self.contentMode = .bottom
                super.attributedText = combinedContent
                break
            }
        }
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        updateTruncatedText()
    }
}

使用方式

将原来的UILabel替换为BottomTruncationLabel,直接设置文本或富文本即可,它会自动完成截断并将省略号固定在label底部。

内容的提问来源于stack exchange,提问作者hey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 05:18:19