修改另一个视图控制器的对象

Modifying an object of another view controller

我想知道是否可以更改或修改一个对象,例如 AppDelegate.swift 中另一个视图控制器的按钮。 这是我尝试开始但不知何故卡住了。

func application(_ application: UIApplication,didReceiveRemoteNotification userInfo: [AnyHashable : Any],fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {

   if application.applicationState == .active {
        if self.window?.rootViewController is homeViewController {
            //modify a button exist in homeViewController


        }
   }

}

感谢任何帮助。提前致谢。

可以使用NotificationCenter!在您的视图控制器中添加观察者并在您从该视图控制器返回时将其删除(自定义通知)。当您收到通知时 post 它!

如果您不知道如何处理 NotificationCenter 然后参考 !

你真正应该与另一个视图控制器交互的唯一地方是在 segues 期间(如果你使用的是故事板)。即使那样,您也应该让该控制器的视图函数负责更改其按钮的状态,并将一些变量传递给控制器​​,或者更好地设置控制器以侦听通知。然后,您的应用委托或其他控制器可以 post 您的家庭控制器侦听的通知。

这是可能的,但直接称呼另一个 ViewController 的成员会违反责任。为内部交互定义接口协议是一种很好的做法。在这种特殊情况下,创建协议 RemoteNotificationReciverInterface 是个好主意(或者根据一些现代编码风格建议创建 RemoteNotificationReciveable 类型,尽管我发现在这种情况下很难找到合适的形容词):

protocol RemoteNotificationReciverInterface: class {
    func didReciveNotification(info : [AnyHashable : Any])
}

然后扩展你的ViewController(以及任何必须在最顶部对通知做出反应的视图控制器)

extension HomeViewController: RemoteNotificationReciverInterface {
    func didReciveNotification(info : [AnyHashable : Any]) {
        // Chnage you button, ignore para,eters
    }
}

您可以采用UINavigationContorollerUITabBarConroller等将通知转发到它们最顶层的控制器,例如:

extension UINavigationController: RemoteNotificationReciverInterface {
    func didReciveNotification(info : [AnyHashable : Any]) {
        (topViewController as? RemoteNotificationReciverInterface)?.didReciveNotification(info: info)
    }
}

并且可以轻松地从应用程序委托中转发它。

func application(_ application: UIApplication,didReceiveRemoteNotification userInfo: [AnyHashable : Any],fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    if application.applicationState == .active {
        (window?.rootViewController as? RemoteNotificationReciverInterface).didReciveNotification(info: userInfo)
    }
}

您可以使用 NotificationCenter 发送和接收内部通知(注意它们不同于本地和远程通知)。

首先按如下方式创建通知:

extension Notification.Name {
    static let remoteNotificationReceived = Notification.Name("uk.co.company.app.remoteNotificationReceived")
}

然后在要响应的视图控制器中执行如下操作:

class TestViewController: UIViewController {
    var remoteNotificationReceivedObserver: NSObjectProtocol?

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        remoteNotificationReceivedObserver = NotificationCenter.default.addObserver(forName: Notification.Name.remoteNotificationReceived, object: nil, queue: nil, using: { (notification) in
            DispatchQueue.main.async { // because the notification won't be received on the main queue and you want to update the UI which must be done on the main queue.
                // Put the code to change the button here
            }
        })
    }

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)

        if let remoteNotificationReceivedObserver = remoteNotificationReceivedObserver {
            NotificationCenter.default.removeObserver(remoteNotificationReceivedObserver)
        }
    }
}

然后在你应用的其他地方你 post 通知是这样的:

    NotificationCenter.default.post(name: Notification.Name.remoteNotificationReceived, object: nil)