iOS应用退至后台或关闭时,如何恢复屏幕亮度?
解决应用退后台/关闭时无法恢复屏幕亮度的问题
问题描述
我的应用内有一个展示条码的页面(作为TabView中的标签页),当用户进入该页面时,将屏幕亮度设置为最大值;用户离开页面时恢复为原始亮度。但当用户将应用退至后台或完全关闭时,亮度无法恢复。
尝试了以下Swift代码,通过.onDisappear和监听scenePhase切换至.background时恢复亮度:
struct BarcodeView: View { @Environment(\.scenePhase) var scenePhase @State private var originalBrightness: CGFloat = 0.0 var body: some View { Barcode() .onAppear { originalBrightness = UIScreen.main.brightness UIScreen.main.brightness = 1.0 } .onDisappear { UIScreen.main.brightness = originalBrightness } .onChange(of: scenePhase) { _, newPhase in if newPhase == .background { UIScreen.main.brightness = originalBrightness } } } }
虽然这些修饰符会触发,但屏幕亮度并未改变。经了解这是苹果的预期行为——应用在非活跃状态下无法修改亮度设置。请问是否有恢复原始屏幕亮度的可行方法?
可行解决方案
方案1:通过AppDelegate监听应用生命周期
苹果允许应用在即将进入后台或终止的瞬间(此时应用仍处于短暂活跃状态)修改系统设置,我们可以利用AppDelegate的生命周期方法实现恢复逻辑,同时需要将原始亮度值存储到全局可访问的位置:
- 创建全局亮度管理单例
class BrightnessManager { static let shared = BrightnessManager() var originalBrightness: CGFloat = 0.0 }
- 修改BarcodeView,用单例存储原始亮度
struct BarcodeView: View { let brightnessManager = BrightnessManager.shared var body: some View { Barcode() .onAppear { brightnessManager.originalBrightness = UIScreen.main.brightness UIScreen.main.brightness = 1.0 } .onDisappear { UIScreen.main.brightness = brightnessManager.originalBrightness } } }
- 实现AppDelegate的生命周期回调
class AppDelegate: NSObject, UIApplicationDelegate { let brightnessManager = BrightnessManager.shared func applicationDidEnterBackground(_ application: UIApplication) { UIScreen.main.brightness = brightnessManager.originalBrightness } func applicationWillTerminate(_ application: UIApplication) { UIScreen.main.brightness = brightnessManager.originalBrightness } }
- 在App结构体中注册AppDelegate
@main struct YourApp: App { @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate var body: some Scene { WindowGroup { TabView { BarcodeView() .tabItem { Label("条码", systemImage: "barcode.viewfinder") } // 其他标签页 } } } }
方案2:基于SceneDelegate的场景生命周期处理(iOS 13+)
如果应用采用Scene-Based架构,可在SceneDelegate中监听场景状态变化:
复用上述
BrightnessManager单例实现SceneDelegate的生命周期方法
class SceneDelegate: UIResponder, UIWindowSceneDelegate { let brightnessManager = BrightnessManager.shared func sceneDidEnterBackground(_ scene: UIScene) { UIScreen.main.brightness = brightnessManager.originalBrightness } func sceneWillResignActive(_ scene: UIScene) { UIScreen.main.brightness = brightnessManager.originalBrightness } func sceneWillTerminate(_ scene: UIScene) { UIScreen.main.brightness = brightnessManager.originalBrightness } }
核心说明
- 应用进入后台后确实无法修改亮度,但在
applicationDidEnterBackground、sceneDidEnterBackground等回调触发时,应用还未完全进入非活跃状态,此时可以执行亮度修改操作。 - 使用全局单例存储原始亮度,避免View的
@State变量在应用退后台时无法被正确访问的问题。
内容的提问来源于stack exchange,提问作者Pieter
相关产品推荐
相关产品推荐

