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

如何在RTL模式下实现带图标与文本的NSAttributedString镜像显示?

问题:UIButton中带图标的NSAttributedString无法适配RTL布局

我有一个UIButton,其文本是由图标(通过字体实现的NSAttributedString)和普通文本拼接成的NSAttributedString。LTR模式下图标在左、文本在右,但切换到阿拉伯语、希伯来语等RTL语言时,图标始终停在左侧,无法自动切换到右侧。

目前构建富文本的代码:

var iconText = NSAttributedString(fontName: fontName, fontSize: fontPointSize, fontValue: fontValue, color: color ?? iconColor)
let iconTextRange = NSRange(location: 0, length: iconText.count)
let iconAttrs: [NSAttributedString.Key: Any] = [.font: icon.font(pointSize: pointSize),
                                                .foregroundColor: iconColor]

if !text.isEmpty {
    iconText = "\(iconText) \(text)"
}

let attributeString = NSMutableAttributedString(string: iconText, attributes: textAttrs)
attributeString.addAttributes(iconAttrs, range: iconTextRange)
return attributeString

之前在其他场景用以下方法实现RTL适配,但此处无效:

public extension NSAttributedString {
    /// Returns an identical attributed string that'll adjust its direction based on the device's configured language.
    func rightToLeftAdjusted() -> NSAttributedString {
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.baseWritingDirection = .natural
        
        let attrs: [NSAttributedString.Key: Any] = [.paragraphStyle: paragraphStyle]
        let range = NSRange(location: 0, length: length)
        
        let copy = NSMutableAttributedString(attributedString: self)
        copy.addAttributes(attrs, range: range)
        
        return copy
    }
}
解决方案

方法1:根据系统布局方向动态调整拼接顺序

直接判断当前系统的布局方向,从根源上改变图标和文本的拼接顺序,这是最可靠的方案:

var iconText = NSAttributedString(fontName: fontName, fontSize: fontPointSize, fontValue: fontValue, color: color ?? iconColor)
let iconAttrs: [NSAttributedString.Key: Any] = [.font: icon.font(pointSize: pointSize),
                                                .foregroundColor: iconColor]

let attributeString = NSMutableAttributedString()
// 获取当前系统布局方向
let isRTL = UIApplication.shared.userInterfaceLayoutDirection == .rightToLeft

if !text.isEmpty {
    if isRTL {
        // RTL模式:文本在前,图标在后
        attributeString.append(NSAttributedString(string: text, attributes: textAttrs))
        attributeString.append(NSAttributedString(string: " "))
        attributeString.append(iconText)
    } else {
        // LTR模式:图标在前,文本在后
        attributeString.append(iconText)
        attributeString.append(NSAttributedString(string: " "))
        attributeString.append(NSAttributedString(string: text, attributes: textAttrs))
    }
} else {
    attributeString.append(iconText)
}

// 为图标应用样式,根据布局方向调整范围
let iconRange = isRTL ? NSRange(location: text.count + 1, length: iconText.length) : NSRange(location: 0, length: iconText.length)
attributeString.addAttributes(iconAttrs, range: iconRange)

return attributeString

方法2:利用UIButton的语义属性自动适配

通过设置按钮的语义属性,让按钮自动翻转内容布局,配合富文本的段落样式使用:

  1. 配置按钮的语义属性:
// 让按钮跟随系统语言自动调整布局方向
button.semanticContentAttribute = .natural
// 同时确保按钮的内容对齐方式适配
button.contentHorizontalAlignment = .leading
  1. 保留你现有的rightToLeftAdjusted扩展,确保富文本的段落样式正确应用。

方法3:使用Unicode控制字符强制方向

在字符串中插入Unicode方向控制标记,告诉系统解析文本的顺序,适合简单场景:

let isRTL = UIApplication.shared.userInterfaceLayoutDirection == .rightToLeft
// Unicode控制字符:\u{200F}强制RTL,\u{200E}强制LTR
let directionMarker = isRTL ? "\u{200F}" : "\u{200E}"

var iconText = NSAttributedString(fontName: fontName, fontSize: fontPointSize, fontValue: fontValue, color: color ?? iconColor)
let iconTextRange = NSRange(location: 0, length: iconText.count)
let iconAttrs: [NSAttributedString.Key: Any] = [.font: icon.font(pointSize: pointSize),
                                                .foregroundColor: iconColor]

if !text.isEmpty {
    if isRTL {
        iconText = "\(text) \(iconText)\(directionMarker)"
    } else {
        iconText = "\(directionMarker)\(iconText) \(text)"
    }
}

let attributeString = NSMutableAttributedString(string: iconText, attributes: textAttrs)
attributeString.addAttributes(iconAttrs, range: iconTextRange)
return attributeString

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 20:50:31