You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关闭通知设置浮层/从应用设置返回时viewWillAppear不触发如何解决

问题原因

viewWillAppear 属于视图控制器的生命周期方法,仅在当前控制器的视图被添加/移除出App视图层级、或者被其他控制器弹出/覆盖时才会触发。你遇到的两类场景均为系统级行为,不会触发当前VC的生命周期回调:

  • 通知设置浮层是系统级弹窗,不属于当前App的视图层级,不会影响你业务VC的生命周期
  • 跳转到系统设置App是将当前App切到后台,你的VC视图没有被移除,自然不会触发生命周期方法

解决方案

你可以通过监听系统通知的方式覆盖这两类场景,以下是可直接落地的实现方案:

方案1:监听App全局活跃通知(兼容所有iOS版本)

只要App从非活跃状态恢复到前台活跃,就会触发该通知,完全覆盖你提到的关闭系统浮层、从设置页返回两个场景。

  1. 在视图控制器的viewDidLoad中添加观察者:
override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(handleAppBecomeActive),
        name: UIApplication.didBecomeActiveNotification,
        object: nil
    )
}
  1. 实现回调方法,可自行添加判断确保只有当前VC对用户可见时才执行业务逻辑:
@objc private func handleAppBecomeActive() {
    // 仅当前VC已加载且在视图层级中时执行逻辑
    guard isViewLoaded, view.window != nil else { return }
    // 在这里写你原本要在viewWillAppear中执行的逻辑,比如刷新权限状态、更新UI
}
  1. 页面销毁时移除观察者避免内存泄漏:
deinit {
    NotificationCenter.default.removeObserver(
        self,
        name: UIApplication.didBecomeActiveNotification,
        object: nil
    )
}

方案2:监听场景活跃通知(适用于iOS 13+多场景App)

如果你的App支持多窗口,使用场景级的通知更精准,避免其他窗口活跃导致的误触发:

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(handleSceneBecomeActive),
        name: UIScene.didActivateNotification,
        object: view.window?.windowScene
    )
}

@objc private func handleSceneBecomeActive() {
    guard isViewLoaded, view.window != nil else { return }
    // 执行业务逻辑
}

扩展优化

如果需要区分「是从系统设置页返回」还是「其他场景切回前台」,可以添加标记位做判断:

// 标记是否是主动跳转到设置页
private var isJumpedToSettings = false

// 你原本跳转设置的按钮点击方法
@IBAction func openSettingsButtonTapped(_ sender: UIButton) {
    isJumpedToSettings = true
    guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else { return }
    UIApplication.shared.open(settingsUrl)
}

@objc private func handleAppBecomeActive() {
    guard isViewLoaded, view.window != nil else { return }
    if isJumpedToSettings {
        // 只有从设置页返回才执行的专属逻辑
        isJumpedToSettings = false // 用完重置标记位
    }
    // 所有切回前台都要执行的通用逻辑
}

内容的提问来源于stack exchange,提问作者D C T

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 00:30:03