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

iOS开发中如何实现不改变文字宽度仅调整字符高度的垂直压缩效果

iOS 端实现固定宽度下文本垂直压缩效果方案

你提到的Photoshop式垂直压缩文字效果,NSAttributedString 没有提供直接对应的内置属性,可通过以下几种方式实现:

垂直压缩文字效果参考

  • 轻量快速实现:直接对文本控件做y轴单方向缩放
    对承载文本的UILabel、UITextView等控件直接设置形变属性,仅修改y轴缩放比例、x轴保持原比例,完全不会改变文字原有宽度,代码示例:

    let textLabel = UILabel()
    textLabel.text = "需要垂直压缩的文本内容"
    textLabel.font = .systemFont(ofSize: 16)
    textLabel.sizeToFit()
    // y轴参数小于1为压缩,大于1为拉伸,x轴固定为1.0保证宽度不变
    textLabel.transform = CGAffineTransform(scaleX: 1.0, y: 0.65)
    

    这个方案实现成本最低,保留原生文本控件的所有交互能力(选中文本、点击链接等),性能开销可以忽略;仅在缩放比例极端(比如小于0.4)时可能出现轻微渲染锯齿,常规业务场景下完全可用。

  • 精细渲染实现:自定义绘制时做上下文缩放
    如果需要避免形变带来的布局偏移、锯齿问题,可以自定义UILabel子类,在绘制方法内对图形上下文做单轴缩放后再绘制文本:

    class VerticalScaleLabel: UILabel {
        /// 垂直方向缩放比例,<1压缩、>1拉伸
        var verticalScale: CGFloat = 0.65
        override func drawText(in rect: CGRect) {
            guard let ctx = UIGraphicsGetCurrentContext() else {
                super.drawText(in: rect)
                return
            }
            ctx.saveGState()
            // 做y轴缩放的同时平移坐标系,避免文本位置偏移
            ctx.scaleBy(x: 1.0, y: verticalScale)
            let offsetY = (rect.height - rect.height / verticalScale) / 2
            ctx.translateBy(x: 0, y: offsetY)
            super.drawText(in: rect)
            ctx.restoreGState()
        }
    }
    

    这个方案不会修改控件本身的frame和点击热区,渲染效果更稳定,适合对布局精度要求高的场景。

  • 复杂排版场景:CoreText 自定义字形变换
    如果需要在图文混排、逐字自定义效果的场景下实现垂直压缩,可以通过CoreText接口给每个字形设置单轴缩放的CGAffineTransform,将变换后的内容封装为富文本属性使用。这个方案灵活度最高,但实现复杂度也更高,适合专业排版类需求。

避坑提示:不要通过缩小字体字号再反向拉伸x轴的方式模拟效果,这种方式会改变字符的实际排版宽度,无法实现和PS一致的固定宽度压缩效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 00:54:39