如何根据用户偏好更改LaunchScreen的主题模式?
解决LaunchScreen跟随用户主题偏好的问题
问题根源
LaunchScreen是应用启动前由系统直接渲染的静态界面,此时你的App代码还未执行,无法读取@AppStorage中的用户主题设置,所以它会默认遵循系统全局的主题模式,而不是用户在App内设置的偏好。
解决方案
要让LaunchScreen跟随用户偏好,需要让系统记住App的界面样式偏好,具体步骤如下:
完善ThemeMode枚举
给枚举添加对应UIUserInterfaceStyle的属性,方便后续设置系统级的界面样式:enum ThemeMode: String { case system, light, dark // 对应SwiftUI的ColorScheme var colorScheme: ColorScheme? { switch self { case .system: return nil case .light: return .light case .dark: return .dark } } // 对应UIKit的用户界面样式 var interfaceStyle: UIUserInterfaceStyle { switch self { case .system: return .unspecified case .light: return .light case .dark: return .dark } } static func fromString(_ string: String) -> ThemeMode { ThemeMode(rawValue: string) ?? .system } }修改App启动逻辑
在App初始化时读取用户主题设置,同步设置系统级的界面样式;同时监听主题变化,实时更新:@main struct MyApp: App { @AppStorage("themeMode") var themeMode: String = ThemeMode.system.rawValue private let initialTheme: ThemeMode init() { initialTheme = ThemeMode.fromString(themeMode) // 启动时设置应用界面样式,让系统持久化这个偏好 if let window = UIApplication.shared.windows.first { window.overrideUserInterfaceStyle = initialTheme.interfaceStyle } } var body: some Scene { WindowGroup { GeometryReader { proxy in ApplicationView() .preferredColorScheme(initialTheme.colorScheme) .onChange(of: themeMode) { newValue in let newTheme = ThemeMode.fromString(newValue) // 用户切换主题时,同步更新系统界面样式 if let window = UIApplication.shared.windows.first { window.overrideUserInterfaceStyle = newTheme.interfaceStyle } } } } } }确保LaunchScreen资源自适应
你的LaunchScreen.storyboard或Asset Catalog中的资源(图片、颜色)必须设置了Light/Dark变体,这样系统才能根据应用的界面样式偏好加载对应的资源。比如在Asset Catalog中给颜色添加Dark模式的取值,给图片添加Dark版本。
原理说明
通过overrideUserInterfaceStyle设置应用的界面样式后,系统会将这个偏好持久化存储。下次应用启动时,系统渲染LaunchScreen会优先读取这个应用级的偏好,而不是系统全局主题,从而实现LaunchScreen与用户设置的主题一致。当用户选择「系统」模式时,overrideUserInterfaceStyle设为.unspecified,LaunchScreen会自动跟随系统主题,符合预期。
内容的提问来源于stack exchange,提问作者cgutierr
相关产品推荐
相关产品推荐

