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

如何为含不同字体的NSMutableAttributedString添加统一删除线?

解决NSAttributedString不同字号文字删除线断裂问题

你的问题是:用两种字号展示货币文本(比如整数部分大字号、小数部分小字号)时,给整个字符串加系统默认删除线会因为字号不同导致删除线位置错开,变成两段断裂的线,想要一条统一贯穿的删除线。

系统默认删除线是基于每个字符的字体基线计算位置的,不同字号的字体基线垂直位置不同,自然会导致删除线错位。下面给你两种解决方法:

方法1:iOS 15+ 用系统属性统一偏移

iOS15及以上新增了strikethroughOffset属性,可手动调整删除线的垂直位置,把不同字号部分的删除线对齐到同一水平线。

示例代码:

// 假设你的字符串分为两个范围:largeRange是大字号部分,smallRange是小字号部分
let largeFont = UIFont.systemFont(ofSize: 24)
let smallFont = UIFont.systemFont(ofSize: 16)

// 计算统一的删除线位置(这里以大字号的垂直中心为基准)
let largeMidY = (largeFont.ascender - largeFont.descender) / 2
let smallMidY = (smallFont.ascender - smallFont.descender) / 2
// 小字号需要的偏移量,让它的删除线对齐大字号的位置
let smallOffset = largeMidY - smallMidY

// 给整个字符串添加基础删除线属性
value.addAttributes([
    NSAttributedString.Key.strikethroughStyle: NSUnderlineStyle.single.rawValue,
    NSAttributedString.Key.strikethroughColor: UIColor.black
], range: value.range)

// 给小字号部分设置偏移,修正删除线位置
value.addAttribute(NSAttributedString.Key.strikethroughOffset, value: smallOffset, range: smallRange)

方法2:自定义绘制(兼容低版本iOS)

如果需要支持iOS15以下系统,可以自定义UILabel,在文本绘制完成后手动画一条贯穿整个标签的横线:

class UnifiedStrikeThroughLabel: UILabel {
    override func draw(_ rect: CGRect) {
        super.draw(rect)
        
        // 计算线条垂直位置(这里取标签垂直中心,你也可以根据需求调整)
        let lineY = rect.midY
        // 定义线条的起始和结束点
        let startPoint = CGPoint(x: rect.minX, y: lineY)
        let endPoint = CGPoint(x: rect.maxX, y: lineY)
        
        // 绘制线条
        let linePath = UIBezierPath()
        linePath.move(to: startPoint)
        linePath.addLine(to: endPoint)
        linePath.lineWidth = 1.0 // 线条粗细可调整
        UIColor.black.setStroke() // 线条颜色可调整
        linePath.stroke()
    }
}

使用这个自定义Label展示你的NSAttributedString,就能得到一条完整、统一的删除线,完全不受字号差异影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 13:32:34