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

时间:2015-01-15 15:00:55

标签: ios xcode swift

我创建了一个使用情节提要的应用程序,并成功创建了一个可以正常工作的tableview和详细信息页面。

我希望用户可以将刷新localNotifications的用户发送到应用内的正确详细信息页面。

看来我可以通过ViewController调用函数,但只要他们引用自己更新任何细节或执行segue,应用程序就会崩溃。

我的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();
}

这是从我的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);
  }
}

println工作正常但是executeSegue失败(致命错误:在展开Optional值时意外发现nil)并且messageView.reload()失败(同样的错误)。

如何在打开时收到将应用程序触发到正确位置的通知?

此解决方案' Get Instance Of ViewController From AppDelegate In Swift'使用大部分相同但我不允许使用ViewController访问任何内容。

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

对于有此问题的其他人。继Gabuh在下面提出的建议之后;我的完整解决方案是做以下事情:

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);
    }
}

这也允许我对视图中的函数进行调用,例如在原始示例中。例如

rootViewController.handleMessageNotificaion(messageID);

rootViewController.messageView.reloadData();

2 个答案:

答案 0 :(得分:0)

您正在创建新ViewController的实例。并且你试图在ViewController上调用一个函数,即当ViewController甚至没有显示时,它试图执行一个segue。我认为这不起作用......

如果要从详细视图中执行segue,则必须访问当前实例化的视图Controller并从中执行segue。

如果您想知道如何获取正在显示的UIViewController的实例,在这篇文章中有几种方法可以告诉您如何操作:

Get the current view controller from the app delegate

在伪代码中,在你的appDelegate中:

1-获取当前的UIViewController实例(不是新实例)

来自该视图控制器的2- perfom segue(或模态或任何你想要的转换)

答案 1 :(得分:0)

在Swift 3中:

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

以上假设

  1. 你不想创建一个全新的VCName实例,只想要一个对它的引用
  2. 您知道要引用的VC是您的根VC