首页 > 解决方案 > 在 UIViewController 的所有现有实例上调用方法

问题描述

我希望能够允许用户通过所有应用程序立即更改图形用户界面的某些属性。为了实现这一点,我考虑过创建一个类似的协议

protocol MyProtocol {
    func changeProperties()
}

因此每个 UIViewController 都可以以自己的方式更改这些属性,然后在所有当前实例化的控制器中调用此方法。

但是,我不知道这是否可能。我的第一个想法是访问应用程序的最根控制器,然后遍历所有子递归调用该方法。就像是

func updatePropertiesFrom(_ vc: UIViewController) {
    for child in vc.childViewControllers {
        if let target = child as? MyProtocol {
            target.changeProperties()
        }

        updatePropertiesFrom(child)
    }
}

let appRootController = ...
updatePropertiesFrom(appRootController)

我不知道如何获得那个 appRootController,我想知道是否有更优雅的方法可以做到这一点。谢谢。

标签: iosswiftuiviewcontrollerprotocols

解决方案


您可以使用NotificationCenter. 例如定义一个通知名称:

extension Notification.Name {
    static let changeViewProperties = Notification.Name(Bundle.main.bundleIdentifier! + ".changeViewProperties")
}

然后,您的各种视图控制器可以注册以在发布此通知时收到通知:

NotificationCenter.default.addObserver(forName: .changeViewProperties, object: nil, queue: .main) { _ in
    // do something here
}

(如果您支持 iOS 9 之前的 iOS 版本,请确保在 中删除您的观察者deinit。)

并在您要启动更改时发布通知:

NotificationCenter.default.post(name: .changeViewProperties, object: nil)

推荐阅读