在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
相关产品推荐
相关产品推荐

