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

如何让NSAttributedString实现的分隔线强制填充指定宽度?

解决固定宽度分隔线的实现问题

你当前用删除线样式结合空白字符实现的分隔线,受字体、排版影响无法稳定控制宽度。要实现指定宽度(比如300px)的分隔线,推荐用NSTextAttachment的方式,这是最可靠的方案:

方法一:基于NSTextAttachment的固定宽度分隔线

直接绘制指定宽度的线条作为文本附件,嵌入富文本中,宽度完全可控:

extension NSAttributedString {
    static func separator(withWidth width: CGFloat) -> NSAttributedString {
        // 创建文本附件
        let attachment = NSTextAttachment()
        // 线条高度可根据需求调整,这里设为1px
        let lineHeight: CGFloat = 1
        // 调整附件垂直位置,让线条和文本基线对齐(适配系统字体)
        let font = UIFont.systemFont(ofSize: 17)
        let yOffset = (font.descender + lineHeight) / 2
        attachment.bounds = CGRect(x: 0, y: yOffset, width: width, height: lineHeight)
        
        // 绘制灰色线条
        let renderer = UIGraphicsImageRenderer(size: CGSize(width: width, height: lineHeight))
        attachment.image = renderer.image { context in
            UIColor.lightGray.setFill()
            context.fill(CGRect(x: 0, y: 0, width: width, height: lineHeight))
        }
        
        // 组合换行符和分隔线,控制上下间距
        let prefix = NSAttributedString(string: "\n\n")
        let separatorAttachment = NSAttributedString(attachment: attachment)
        let suffix = NSAttributedString(string: "\n\n")
        
        let result = NSMutableAttributedString()
        result.append(prefix)
        result.append(separatorAttachment)
        result.append(suffix)
        return result
    }
}

使用方式

attributed.append(.separator(withWidth: 300))

方法二:基于删除线的兼容方案(不推荐)

如果坚持用删除线样式,可以通过计算固定数量的全角空格来凑宽度,但这种方法依赖字体,不同字体下宽度会有偏差:

extension NSAttributedString {
    static func separator(withWidth width: CGFloat) -> NSAttributedString {
        let font = UIFont.systemFont(ofSize: 17)
        // 计算单个全角空格的宽度
        let singleSpaceWidth = font.stringWidth(" ")
        // 计算需要的空格数量
        let spaceCount = Int(ceil(width / singleSpaceWidth))
        let spaceString = String(repeating: " ", count: spaceCount)
        
        let attributes: [NSAttributedString.Key: Any] = [
            .strikethroughStyle: NSUnderlineStyle.single.rawValue,
            .strikethroughColor: UIColor.lightGray,
            .font: font
        ]
        return NSAttributedString(string: "\n\n\(spaceString)\n\n", attributes: attributes)
    }
}

// 给UIFont加扩展,计算字符串宽度
extension UIFont {
    func stringWidth(_ string: String) -> CGFloat {
        let attributes = [NSAttributedString.Key.font: self]
        return string.size(withAttributes: attributes).width
    }
}

说明

优先选择方法一,因为它不依赖字体和排版规则,能精准控制分隔线宽度,适配各种场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 03:22:20