|
|
import Foundation
|
|
|
import SwiftUI
|
|
|
import Combine
|
|
|
|
|
|
// 支持的语言枚举
|
|
|
enum Language: String, CaseIterable {
|
|
|
case system = "system"
|
|
|
case english = "en"
|
|
|
case chinese = "zh-Hans"
|
|
|
case japanese = "ja"
|
|
|
case korean = "ko"
|
|
|
case french = "fr"
|
|
|
case german = "de"
|
|
|
case spanish = "es"
|
|
|
case italian = "it"
|
|
|
case portuguese = "pt"
|
|
|
case russian = "ru"
|
|
|
case thai = "th"
|
|
|
|
|
|
var displayName: String {
|
|
|
switch self {
|
|
|
case .system:
|
|
|
return "system_language".localized
|
|
|
case .english:
|
|
|
return "English"
|
|
|
case .thai:
|
|
|
return "ไทย"
|
|
|
case .japanese:
|
|
|
return "日本語"
|
|
|
case .korean:
|
|
|
return "한국어"
|
|
|
case .french:
|
|
|
return "Français"
|
|
|
case .german:
|
|
|
return "Deutsch"
|
|
|
case .spanish:
|
|
|
return "Español"
|
|
|
case .italian:
|
|
|
return "Italiano"
|
|
|
case .portuguese:
|
|
|
return "Português"
|
|
|
case .russian:
|
|
|
return "Русский"
|
|
|
case .chinese:
|
|
|
return "中文"
|
|
|
}
|
|
|
}
|
|
|
|
|
|
var flag: String {
|
|
|
switch self {
|
|
|
case .system:
|
|
|
return "🌐"
|
|
|
case .english:
|
|
|
return "🇺🇸"
|
|
|
case .chinese:
|
|
|
return "🇨🇳"
|
|
|
case .japanese:
|
|
|
return "🇯🇵"
|
|
|
case .korean:
|
|
|
return "🇰🇷"
|
|
|
case .french:
|
|
|
return "🇫🇷"
|
|
|
case .german:
|
|
|
return "🇩🇪"
|
|
|
case .spanish:
|
|
|
return "🇪🇸"
|
|
|
case .italian:
|
|
|
return "🇮🇹"
|
|
|
case .portuguese:
|
|
|
return "🇵🇹"
|
|
|
case .russian:
|
|
|
return "🇷🇺"
|
|
|
case .thai:
|
|
|
return "🇹🇭"
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 语言管理器
|
|
|
class LanguageManager: ObservableObject {
|
|
|
static let shared = LanguageManager()
|
|
|
|
|
|
@Published var currentLanguage: Language = .english
|
|
|
@Published var refreshTrigger = UUID() // 用于强制刷新UI
|
|
|
|
|
|
private let languageKey = "selected_language"
|
|
|
private let systemLanguageKey = "system_language"
|
|
|
|
|
|
private init() {
|
|
|
loadLanguage()
|
|
|
}
|
|
|
|
|
|
// 检测系统语言并返回对应的支持语言
|
|
|
private func detectSystemLanguage() -> Language {
|
|
|
// 获取系统语言代码(兼容iOS 15+)
|
|
|
let systemLanguage = Locale.current.languageCode ?? "en"
|
|
|
|
|
|
// 检查是否是简体中文
|
|
|
if systemLanguage.hasPrefix("zh") {
|
|
|
return .chinese
|
|
|
}
|
|
|
|
|
|
// 检查是否是日语
|
|
|
if systemLanguage == "ja" {
|
|
|
return .japanese
|
|
|
}
|
|
|
|
|
|
// 检查是否是韩语
|
|
|
if systemLanguage == "ko" {
|
|
|
return .korean
|
|
|
}
|
|
|
|
|
|
// 检查是否是法语
|
|
|
if systemLanguage == "fr" {
|
|
|
return .french
|
|
|
}
|
|
|
|
|
|
// 检查是否是德语
|
|
|
if systemLanguage == "de" {
|
|
|
return .german
|
|
|
}
|
|
|
|
|
|
// 检查是否是西班牙语
|
|
|
if systemLanguage == "es" {
|
|
|
return .spanish
|
|
|
}
|
|
|
|
|
|
// 检查是否是意大利语
|
|
|
if systemLanguage == "it" {
|
|
|
return .italian
|
|
|
}
|
|
|
|
|
|
// 检查是否是葡萄牙语
|
|
|
if systemLanguage == "pt" {
|
|
|
return .portuguese
|
|
|
}
|
|
|
|
|
|
// 检查是否是俄语
|
|
|
if systemLanguage == "ru" {
|
|
|
return .russian
|
|
|
}
|
|
|
|
|
|
// 检查是否是泰文
|
|
|
if systemLanguage == "th" {
|
|
|
return .thai
|
|
|
}
|
|
|
|
|
|
// 其他语言默认使用英文
|
|
|
return .english
|
|
|
}
|
|
|
|
|
|
// 加载保存的语言设置
|
|
|
private func loadLanguage() {
|
|
|
// 检查是否已经手动设置过语言
|
|
|
let hasManualLanguage = UserDefaults.standard.object(forKey: languageKey) != nil
|
|
|
|
|
|
if hasManualLanguage {
|
|
|
// 如果用户手动设置过语言,使用保存的设置
|
|
|
if let savedLanguage = UserDefaults.standard.string(forKey: languageKey),
|
|
|
let language = Language(rawValue: savedLanguage) {
|
|
|
if language == .system {
|
|
|
// 如果保存的是系统语言,检测当前系统语言
|
|
|
let systemLanguage = detectSystemLanguage()
|
|
|
currentLanguage = systemLanguage
|
|
|
} else {
|
|
|
currentLanguage = language
|
|
|
}
|
|
|
} else {
|
|
|
currentLanguage = .english
|
|
|
}
|
|
|
} else {
|
|
|
// 首次启动,默认使用系统语言
|
|
|
currentLanguage = .system
|
|
|
_ = detectSystemLanguage()
|
|
|
|
|
|
// 保存系统语言设置
|
|
|
UserDefaults.standard.set("system", forKey: languageKey)
|
|
|
UserDefaults.standard.set(true, forKey: systemLanguageKey)
|
|
|
|
|
|
// 设置实际语言
|
|
|
switchLanguage(to: .system)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 切换语言
|
|
|
func switchLanguage(to language: Language) {
|
|
|
currentLanguage = language
|
|
|
|
|
|
if language == .system {
|
|
|
// 如果选择跟随系统,重置为系统语言
|
|
|
resetToSystemLanguage()
|
|
|
} else {
|
|
|
// 手动选择语言
|
|
|
UserDefaults.standard.set(language.rawValue, forKey: languageKey)
|
|
|
UserDefaults.standard.set(false, forKey: systemLanguageKey)
|
|
|
|
|
|
// 强制刷新所有UI
|
|
|
refreshTrigger = UUID()
|
|
|
|
|
|
// 通知语言变化
|
|
|
NotificationCenter.default.post(name: .languageChanged, object: language)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 重置为系统语言
|
|
|
func resetToSystemLanguage() {
|
|
|
let systemLanguage = detectSystemLanguage()
|
|
|
currentLanguage = systemLanguage
|
|
|
UserDefaults.standard.set(systemLanguage.rawValue, forKey: languageKey)
|
|
|
UserDefaults.standard.set(true, forKey: systemLanguageKey)
|
|
|
|
|
|
// 强制刷新所有UI
|
|
|
refreshTrigger = UUID()
|
|
|
|
|
|
// 通知语言变化
|
|
|
NotificationCenter.default.post(name: .languageChanged, object: systemLanguage)
|
|
|
}
|
|
|
|
|
|
// 检查当前是否使用系统语言
|
|
|
var isUsingSystemLanguage: Bool {
|
|
|
return UserDefaults.standard.bool(forKey: systemLanguageKey)
|
|
|
}
|
|
|
|
|
|
// 获取本地化字符串
|
|
|
func localizedString(for key: String) -> String {
|
|
|
let bundle = Bundle.main
|
|
|
|
|
|
// 确定要使用的语言
|
|
|
let languageToUse: String
|
|
|
if currentLanguage == .system {
|
|
|
// 如果选择跟随系统,检测系统语言
|
|
|
let systemLanguage = detectSystemLanguage()
|
|
|
languageToUse = systemLanguage.rawValue
|
|
|
} else {
|
|
|
languageToUse = currentLanguage.rawValue
|
|
|
}
|
|
|
|
|
|
// 首先尝试从当前语言获取字符串
|
|
|
if let path = bundle.path(forResource: languageToUse, ofType: "lproj"),
|
|
|
let languageBundle = Bundle(path: path) {
|
|
|
let localizedString = languageBundle.localizedString(forKey: key, value: nil, table: nil)
|
|
|
|
|
|
// 如果返回的字符串不是key本身,说明找到了本地化条目
|
|
|
if localizedString != key {
|
|
|
return localizedString
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 如果当前语言没有找到条目,回退到英语
|
|
|
if let path = bundle.path(forResource: "en", ofType: "lproj"),
|
|
|
let languageBundle = Bundle(path: path) {
|
|
|
let englishString = languageBundle.localizedString(forKey: key, value: nil, table: nil)
|
|
|
|
|
|
// 如果英语也没有找到,返回key本身
|
|
|
if englishString != key {
|
|
|
return englishString
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 最后回退到key本身
|
|
|
return key
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 本地化字符串扩展
|
|
|
extension String {
|
|
|
var localized: String {
|
|
|
return LanguageManager.shared.localizedString(for: self)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 响应式本地化文本视图
|
|
|
struct LocalizedText: View {
|
|
|
let key: String
|
|
|
@ObservedObject private var languageManager = LanguageManager.shared
|
|
|
|
|
|
init(_ key: String) {
|
|
|
self.key = key
|
|
|
}
|
|
|
|
|
|
var body: some View {
|
|
|
Text(languageManager.localizedString(for: key))
|
|
|
.id(languageManager.refreshTrigger) // 强制刷新
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 通知名称扩展
|
|
|
extension Notification.Name {
|
|
|
static let languageChanged = Notification.Name("languageChanged")
|
|
|
}
|