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

在Xcode与SwiftUI中如何避免预览字符串写入Localizable.xcstrings?

避免SwiftUI预览中的自定义视图字符串被写入Localizable.xcstrings的方案

核心思路

Xcode的本地化扫描工具会识别传递给Text(_:)的字符串并自动加入Localizable.xcstrings,但会忽略Text(verbatim:)的参数。要实现业务代码字符串正常被扫描、预览字符串被排除,需要让自定义视图在预览场景下使用Text(verbatim:)渲染文本,业务场景下保留默认的本地化支持。


方案1:添加预览专用初始化器

给自定义视图新增一个专门用于预览的初始化方法,内部强制使用verbatim模式渲染文本,同时保留原初始化器供业务代码使用:

struct PairView: View {
    let left: String
    let right: String
    private let useVerbatim: Bool

    // 业务代码使用:默认启用本地化扫描
    init(left: String, right: String) {
        self.left = left
        self.right = right
        self.useVerbatim = false
    }

    // 预览专用:强制使用verbatim模式,避免扫描
    init(verbatimLeft: String, verbatimRight: String) {
        self.left = verbatimLeft
        self.right = verbatimRight
        self.useVerbatim = true
    }

    var body: some View {
        HStack(alignment: .firstTextBaseline) {
            let leftText = useVerbatim ? Text(verbatim: left) : Text(left)
            let rightText = useVerbatim ? Text(verbatim: right) : Text(right)
            
            leftText.foregroundColor(.black)
            rightText.foregroundColor(.gray)
        }
    }
}

预览代码示例:

#Preview {
    PairView(verbatimLeft: "nacho", verbatimRight: "4d")
}

优点:修改量小,逻辑清晰,业务代码无需改动;缺点:需要记住预览时使用专用初始化器。


方案2:用类型区分本地化/非本地化字符串

定义一个VerbatimString包装类型,让自定义视图根据参数类型自动选择渲染方式,实现类型安全的区分:

// 包装非本地化字符串的类型,支持字符串字面量初始化
struct VerbatimString: ExpressibleByStringLiteral {
    let value: String
    init(stringLiteral value: StringLiteralType) {
        self.value = value
    }
}

struct PairView: View {
    private let leftContent: Text
    private let rightContent: Text

    // 业务代码使用:接受普通String,生成可本地化的Text
    init(left: String, right: String) {
        self.leftContent = Text(left).foregroundColor(.black)
        self.rightContent = Text(right).foregroundColor(.gray)
    }

    // 预览使用:接受VerbatimString,生成非本地化的Text
    init(left: VerbatimString, right: VerbatimString) {
        self.leftContent = Text(verbatim: left.value).foregroundColor(.black)
        self.rightContent = Text(verbatim: right.value).foregroundColor(.gray)
    }

    var body: some View {
        HStack(alignment: .firstTextBaseline) {
            leftContent
            rightContent
        }
    }
}

预览代码示例:

#Preview {
    // 直接传字符串字面量,编译器自动推断为VerbatimString
    PairView(left: "nacho", right: "4d")
}

优点:类型安全,预览代码写法和业务代码一致,无需额外记忆;缺点:需要新增包装类型,代码量稍大。


方案3:编译条件控制(谨慎使用)

利用DEBUG编译条件,在调试模式下强制使用verbatim,但注意该方案会让Debug运行的APP也跳过本地化:

struct PairView: View {
    let left: String
    let right: String

    var body: some View {
        HStack(alignment: .firstTextBaseline) {
            #if DEBUG
            Text(verbatim: left).foregroundColor(.black)
            Text(verbatim: right).foregroundColor(.gray)
            #else
            Text(left).foregroundColor(.black)
            Text(right).foregroundColor(.gray)
            #endif
        }
    }
}

优点:无需修改初始化逻辑;缺点:Debug运行时业务字符串也不会被本地化,仅适合对调试本地化无要求的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 07:05:15