Xcode 15 String Catalog强制用户选择语言翻译失效问题求助
针对你遇到的SwiftUI视图正常显示自定义语言,但手动调用String(localized:locale:)返回系统语言翻译的问题,以下是几个可行的解决思路:
1. 利用SwiftUI环境Locale + LocalizedStringResource
String Catalog推荐使用LocalizedStringResource类型管理本地化字符串,结合SwiftUI环境中的Locale可确保字符串解析和视图逻辑完全对齐:
// 在视图中获取环境Locale @Environment(\.locale) private var currentLocale // 定义对应String Catalog键的资源 let greetingResource = LocalizedStringResource("greeting") // 获取目标Locale的翻译 let translatedGreeting = String(localized: greetingResource, locale: currentLocale)
这种方式严格遵循你在主视图设置的environment(\.locale)配置,和SwiftUI视图的本地化逻辑保持一致。
2. 直接通过Bundle获取指定Locale的字符串
绕过String(localized:)初始化器的默认逻辑,直接调用Bundle的本地化方法,明确指定目标Locale和String Catalog对应的table名(默认是Localizable):
func getLocalizedString(_ key: String, for locale: Locale) -> String { return Bundle.main.localizedString( forKey: key, value: key, // 未找到翻译时返回键本身作为兜底 table: "Localizable", // 对应你的String Catalog文件名(去掉.xcstrings后缀) locale: locale ) } // 使用示例 let arabicGreeting = getLocalizedString("greeting", for: Locale(identifier: "ar"))
该方法完全独立于系统语言设置,直接从对应Locale的资源文件读取翻译。
3. 全局强制App语言(覆盖所有场景)
如果希望所有本地化场景(包括弹窗、第三方组件等)都统一使用用户选择的语言,可以修改UserDefaults的语言偏好设置,让整个App的本地化逻辑优先使用该语言:
func setPreferredAppLanguage(_ code: String) { UserDefaults.standard.set([code], forKey: "AppleLanguages") UserDefaults.standard.synchronize() // 刷新根视图以应用新Locale if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene { let rootView = ContentView().environment(\.locale, Locale(identifier: code)) windowScene.windows.first?.rootViewController = UIHostingController(rootView: rootView) } }
调用此方法后,无论是SwiftUI视图还是手动创建的String实例,都会自动使用指定语言翻译,无需额外传参。
旧方法失效原因
String Catalog的本地化解析逻辑和传统Localizable.strings不同:String(localized:locale:)初始化器在使用String Catalog时,会优先参考系统语言列表或UserDefaults中的AppleLanguages设置,而非直接使用传入的Locale参数,这就是你设置环境Locale但手动调用仍返回系统语言的核心原因。
内容的提问来源于stack exchange,提问作者JAHelia

