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

时间:2018-01-09 11:08:31

标签: ios swift uiviewcontroller appdelegate

我想知道是否可以改为或修改对象,如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


        }
   }

}

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

4 个答案:

答案 0 :(得分:2)

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

如果您不知道如何处理NotificationCenter,请参阅This SO post

答案 1 :(得分:2)

您可以使用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)
        }
    }
}

然后在你的应用程序的其他地方发布这样的通知:

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

答案 2 :(得分:1)

你应该真正与另一个vew控制器进行交互的唯一地方就是segues(如果你使用的是Storyboard)。即便如此,您应该让该控制器的视图函数负责更改其按钮的状态,并将一些变量传递给控制器​​,或者更好地设置控制器以监听通知。然后,您的应用代表或其他控制器只能发布您的家庭控制器侦听的通知。

答案 3 :(得分:1)

这是可能的,但直接解决另一个ViewController的成员会破坏责任。为内部交互定义接口协议是一种很好的做法。在这种特殊情况下,最好根据一些现代编码风格建议创建protcol 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
    }
}

您可以采用 UINavigationContoroller UITabBarConroller 等将通知转发给最顶层的控制器,例如:

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

从app delegate轻松转发它。

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