如何从Swift中的Appdelegate调用视图控制器中的方法?

时间:2018-03-14 13:04:56

标签: ios swift appdelegate

enter image description here

此主菜单VC将在应用程序首次启动时或用户返回应用程序后打开(应用程序在进入后台状态后变为活动状态)。

每次打开此主菜单VC时,理想情况下我需要更新日期时间数据来自服务器的时间。在这个主菜单vc类中,我在getDateTimeFromServer()之后调用updateUI()

但要在应用进入后台并返回前台后更新数据,应使用功能从Appdelegate激活getDateTimeFromServer()updateUI()

func applicationWillEnterForeground(application: UIApplication) {

    }

那么如何激活AppDelegate中主菜单VC中存在的方法

4 个答案:

答案 0 :(得分:4)

您无需在app delegate中调用视图控制器方法。观察控制器中的前景事件并从那里调用您的方法。

观察viewController viewDidLoad中的UIApplicationWillEnterForeground通知:

NotificationCenter.default.addObserver(self, selector: #selector(ViewController.yourMethod), name: NSNotification.Name.UIApplicationWillEnterForeground, object: nil)

实现此操作以在用户输入前景时接收回调

@objc func yourMethod() {
     // Call getDateTimeFromServer()
}

答案 1 :(得分:0)

您可以使用名为键值观察的技术做类似的事情:

class CommonObservableData: NSObject {
    // Use @objc and dynamic to ensure enabling Key-Value Observation
    @objc dynamic var dateTime: Date?

    static let shared = CommonObservableData()

    func updateFromWeb() {
        // callWebThen is a function you will define that calls your Web API, then
        // calls a completion handler you define, passing new value to your handler
        callWeb(then: { self.dateTime = $0 })
    }
}

然后你使用Swift 4的新NSKeyValueObservation观察它。

class SomeViewController: UIViewController {
    var kvo: NSKeyValueObservation?
    func viewDidLoad() {
        ...
        kvo = CommonObservableData.shared.observe(
            \CommonObservableData.dateTime, { model, change in

            self.label.text = "\(model.dateTime)"

        })
    }
}

键值观察最初是一种由Swift 4“稍微复活”的Objective-C技术,这种技术允许您观察属性的变化(称为 Key 在Objective-C中的任何对象。

所以,在前面的代码片段中,我们创建了一个类,并使它成为一个单例,这个单例有一个名为dateTime的可观察属性,我们可以观察到这个属性的变化,并在此属性会自动调用我们可以更新UI的方法。

在这里阅读KVO:

Key-Value Observation Apple Programming Guide

Key-Value Observation using Swift 4

此外,如果你喜欢Rx和RFP(反应函数编程),你可以使用RxSwift并使用它以更干净的方式进行观察。

答案 2 :(得分:0)

在大多数情况下,使用By book = By.cssSelector("#button\\.buchung\\.continue"); WebElement element= ConfigClass.driver.findElement(book); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", element); 上下文完成这些类型的消息传递。正如已经提到的那样,您也可以使用视图控制器内的通知中心来通知您的应用程序进入前台。我不鼓励你为此创建自定义通知(但也是一种可能的解决方案)。

无论如何,根据您的具体情况,我建议您使用包含数据的模型。然后创建它的共享实例。

static

现在,当您的视图控制器需要重新加载时,只需使用class MyDataModel { static var shared: MyDataModel = { let model = MyDataModel() model.reloadData() return model }() var myObjects: [MyObject]? func reloadData() { // load data asynchronously } } 作为数据源。

在app delegate中,当app使用MyDataModel.shared.myObjects返回前台时,你所做的只是重新加载。

所以现在代理仍然缺失所以我们添加

MyDataModel.shared.reloadData()

现在,当您的视图控制器出现时,它需要将自己指定为委托protocol MyDataModelDelegate: class { func myDataModel(_ sender: MyDataModel, updatedObjects objects: [MyObject]?) } class MyDataModel { weak var delegate: MyDataModelDelegate? static var shared: MyDataModel = { 。并实现必须在视图上重新加载的协议。

可以在模型设置器中完成对委托的调用:

MyDataModel.shared.delegate = self

答案 3 :(得分:0)

在迅速4和5中,通知名称已更改为以下代码,两者均适用。

    notifyCenter.addObserver(self, selector: #selector(new), name:UIApplication.willEnterForegroundNotification, object: nil)

 @objc func  new(){}