简体   繁体   English

从App Delegate(Swift)调用ViewControllers方法或Segue

[英]Call ViewControllers Method or Segue from App Delegate (Swift)

I have created an app that uses storyboard and have successfully created a tableview and detail page which all works. 我创建了一个使用情节提要的应用程序,并成功创建了一个可以正常工作的表格视图和详细信息页面。

I would like it so that users swiping the localNotifications can be sent to the correct detail page within the app. 我希望这样做,以便将刷了localNotifications的用户发送到应用程序中正确的详细信息页面。

It appears that I can call functions from the ViewController but whenever they refer to themselves to update any details or perform a segue the app crashes. 看来我可以从ViewController调用函数,但是只要它们引用自身以更新任何详细信息或执行测试,应用程序就会崩溃。

The code i have in my ViewController is as follows: 我在ViewController中拥有的代码如下:

func handleMessageNotification (messageID:String)
{
    // this function should act as a conduit for the call from the delegate
    println("notif messageID: \(messageID)");
    self.performSegueWithIdentifier("showMessageDetail", sender: self);
    self.messageView.reloadData();
}

and this is called from my appDelegate 这是从我的appDelegate调用的

func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification) {
  if (application.applicationState == UIApplicationState.Background || application.applicationState == UIApplicationState.Inactive)
    {
        var rootViewController = self.window!.rootViewController
        let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        var setViewController = mainStoryboard.instantiateViewControllerWithIdentifier("ViewController") as ViewController
        rootViewController?.navigationController?.popToViewController(setViewController, animated: false)
        setViewController.handleMessageNotification(messageID);
  }
}

the println works correctly but performSegue fails (fatal error: unexpectedly found nil while unwrapping an Optional value) and the messageView.reload() fails (same error). println可以正常工作,但是performSegue失败(致命错误:在展开Optional值时意外发现nil)并且messageView.reload()失败(相同错误)。

How do I get a notification to fire the app to the correct place upon opening? 我如何获得通知,以在打开应用后将其启动到正确的位置?

This solution ' Get Instance Of ViewController From AppDelegate In Swift ' uses much of the same but mine will not allow access to anything with the ViewController. 此解决方案“ 在Swift中从AppDelegate获取ViewController实例 ”使用了许多相同的解决方案,但我的解决方案不允许使用ViewController访问任何内容。

======= Update - Solution ======= =======更新-解决方案=======

For anyone else with this issue. 对于任何其他有此问题的人。 Following on from what Gabuh had suggested below; 根据加布(Gabuh)的建议: the full solution for me was to do the following: 对我来说,完整的解决方案是执行以下操作:

func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification) {
    if (application.applicationState == UIApplicationState.Background || application.applicationState == UIApplicationState.Inactive)
    {
        let navigationController = application.windows[0].rootViewController as UINavigationController;
        navigationController.popToRootViewControllerAnimated(false); // I need to push back to root before performing segue
        let rootViewController = navigationController.visibleViewController;
        rootViewController.performSegueWithIdentifier("showMessageDetail", sender: self);
    }
}

this also allows me to make calls on functions in the view such as in the original example eg 这也允许我在视图中调用函数,例如在原始示例中

rootViewController.handleMessageNotificaion(messageID);

or 要么

rootViewController.messageView.reloadData();

You are creating an instance of a new ViewController . 您正在创建一个新ViewController的实例。 And you are trying to call a function on that ViewController, that is trying to perform a segue, when the ViewController is not even displayed. 并且您试图在该ViewController上调用一个函数,即试图在甚至不显示ViewController时执行segue。 I think that's not going to work... 我认为那是行不通的...

If you want to perform a segue from your detail view, you have to access to the current instantiated view Controller and perform the segue from it. 如果要从详细视图执行序列,则必须访问当前的实例化视图Controller并从中执行序列。

If you want to know how to get the instance of the UIViewController that is being displayed, in this post there are several ways that show you how to do it: 如果您想知道如何获取正在显示的UIViewController的实例,那么在这篇文章中,有几种方法向您展示如何实现:

Get the current view controller from the app delegate 从应用程序委托获取当前的视图控制器

In pseudo-code, in your appDelegate: 用伪代码在您的appDelegate中:

1- get current UIViewController instance (not new one) 1-获取当前的UIViewController实例(不是新实例)

2- perfom segue from that view controller (or present modally or whatever transition you want) 2-从该视图控制器执行perfom segue(或以模态呈现或您想要的任何过渡)

In Swift 3: 在Swift 3中

    guard let rvc = self.window?.rootViewController as? VCName else { return }
    rvc.methodInYourVC()

The above assumes 以上假设

  1. That you don't want to create a whole new instance of VCName, just want a reference to it 您不想创建一个完整的VCName实例,只需要引用它即可
  2. That you know the VC you want to reference is your root VC 您知道要引用的VC是您的根VC

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM