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

iOS17中traitCollectionDidChange已弃用,替代方案如何使用?

iOS 17 替代废弃的 traitCollectionDidChange 实现明暗模式切换

问题背景

iOS 17 中,traitCollectionDidChange(_:) 方法被废弃,原实现代码如下:

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
    super.traitCollectionDidChange(previousTraitCollection)

    // 检查界面风格是否变化
    if self.traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) {
        // 界面风格已切换(亮→暗或暗→亮)
        if self.traitCollection.userInterfaceStyle == .light {
            // 亮模式执行代码
            print("App switched to light mode")
        } else {
            // 暗模式执行代码
            print("App switched to dark mode")
        }
    }
}

收到的废弃提示:

‘traitCollectionDidChange’ was deprecated in iOS 17.0: Use the trait change registration APIs declared in the UITraitChangeObservable protocol

两种替代方案

1. 使用 registerForTraitChanges(_:handler:) 闭包方式

这种方式代码紧凑,适合直接在当前类内处理简单逻辑,系统会自动管理监听生命周期。

示例代码:

override func viewDidLoad() {
    super.viewDidLoad()
    
    // 注册监听用户界面风格变化
    registerForTraitChanges([UITraitCollection.UserInterfaceStyle.self], handler: { [weak self] (self: Self, _) in
        guard let self = self else { return }
        if self.traitCollection.userInterfaceStyle == .light {
            print("App switched to light mode")
            // 添加亮模式下的业务代码
        } else {
            print("App switched to dark mode")
            // 添加暗模式下的业务代码
        }
    })
}

注意:用[weak self]避免循环引用,闭包第一个参数会自动传入当前实例。

2. 使用 registerForTraitChanges(_:target:action:) 目标动作方式

如果需要把模式切换逻辑分离到单独方法中,或者逻辑需要复用,适合用这种方式。

示例代码:

override func viewDidLoad() {
    super.viewDidLoad()
    
    // 注册监听,指定处理方法
    registerForTraitChanges([UITraitCollection.UserInterfaceStyle.self], target: self, action: #selector(handleInterfaceStyleChange(_:previousTraitCollection:)))
}

@objc private func handleInterfaceStyleChange(_ sender: UITraitChangeObservable, previousTraitCollection: UITraitCollection?) {
    guard let self = sender as? Self else { return }
    if self.traitCollection.userInterfaceStyle == .light {
        print("App switched to light mode")
        // 亮模式业务代码
    } else {
        print("App switched to dark mode")
        // 暗模式业务代码
    }
}

注意:处理方法必须标记@objc,因为通过#selector调用。

方式选择建议

  • 逻辑简单、代码量少:优先用闭包方式,代码更简洁集中
  • 逻辑复杂、需要复用:优先用目标动作方式,职责分离更清晰

内容的提问来源于stack exchange,提问作者Adham Raouf

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 09:40:31