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

Ios 修改另一个视图控制器的对象,ios,swift,uiviewcontroller,appdelegate,Ios,Swift,Uiviewcontroller,Appdelegate,我想知道是否可以,比如说,从AppDelegate.swift更改或修改对象,如另一个视图控制器的按钮。 这是我试图开始的,但不知怎么搞砸了 func application(_ application: UIApplication,didReceiveRemoteNotification userInfo: [AnyHashable : Any],fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResu

我想知道是否可以,比如说,从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!在视图控制器中添加观察者,并在从该视图控制器自定义通知返回时将其删除。当你收到通知后,把它贴出来


如果您不知道如何处理NotificationCenter,请参考

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


如果您不知道如何处理NotificationCenter,请参考

如果您正在使用情节串连板,那么您唯一应该与另一个vew控制器进行交互的地方就是在赛段期间。即使这样,您也应该让该控制器的视图函数负责更改其按钮的状态,并将一些变量传递给控制器,或者更好地设置控制器以侦听通知。然后,您的应用程序代理或其他控制器就可以发布您的家庭控制器侦听的通知。

如果您正在使用故事板,您唯一应该与另一个vew控制器进行交互的地方就是在赛段期间。即使这样,您也应该让该控制器的视图函数负责更改其按钮的状态,并将一些变量传递给控制器,或者更好地设置控制器以侦听通知。然后,您的应用程序代理或其他控制器可以只发布您的主控制器侦听的通知。

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

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

您可以使用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)
然后在要响应的视图控制器中执行以下操作:

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)
然后在应用程序的其他位置发布通知,如下所示:

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)

您可以使用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)
然后在要响应的视图控制器中执行以下操作:

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)
然后在应用程序的其他位置发布通知,如下所示:

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)

理论上这是可能的,但它将打破MVC模式。如果您将rootViewController强制转换为homeViewController,您可以访问他的属性。哦,我明白了。问题是,我想根据收到的通知更新homeViewController中的按钮……那么,除了我有其他选择吗@LorenzoliveTo您可以使用答案中已经发布的NotificationCenter。理论上这是可能的,但它将打破MVC模式。如果您将rootViewController强制转换为homeViewController,您可以访问他的属性。哦,我明白了。问题是,我想根据收到的通知更新homeViewController中的按钮……那么,除了我有其他选择吗@LorenzoliveTo您可以使用已发布在答案中的通知中心。通知中心是一个广播中心。当您需要通知多个实例时,这是合适的。但是,当您需要通知单个对象时,这种情况几乎不存在@
迈克尔沃龙佐夫:如果你使用NotificationCenter通知单个对象,没有什么不对!苹果公司表示,一种通知发送机制可以向注册观察员广播信息,但这并不意味着观察员的数量应该大于一个@迈克尔沃龙佐夫:如果你想打电话给你的朋友,你打算用电话还是通过电台广播?@MichaelVorontsov:嘿嘿!这是不同的情况!或者我可以说那个不相关的例子!通知中心是一个广播中心。当您需要通知多个实例时,这是合适的。但当你需要通知单个对象时,情况就不一样了。@MichaelVorontsov:如果你使用NotificationCenter通知单个对象,没有什么不对!苹果公司表示,一种通知发送机制可以向注册观察员广播信息,但这并不意味着观察员的数量应该大于一个@迈克尔沃龙佐夫:如果你想打电话给你的朋友,你打算用电话还是通过电台广播?@MichaelVorontsov:嘿嘿!这是不同的情况!或者我可以说那个不相关的例子!