繁体   English   中英

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

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

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

我希望这样做,以便将刷了localNotifications的用户发送到应用程序中正确的详细信息页面。

看来我可以从ViewController调用函数,但是只要它们引用自身以更新任何详细信息或执行测试,应用程序就会崩溃。

我在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可以正常工作,但是performSegue失败(致命错误:在展开Optional值时意外发现nil)并且messageView.reload()失败(相同错误)。

我如何获得通知,以在打开应用后将其启动到正确的位置?

此解决方案“ 在Swift中从AppDelegate获取ViewController实例 ”使用了许多相同的解决方案,但我的解决方案不允许使用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();

您正在创建一个新ViewController的实例。 并且您试图在该ViewController上调用一个函数,即试图在甚至不显示ViewController时执行segue。 我认为那是行不通的...

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

如果您想知道如何获取正在显示的UIViewController的实例,那么在这篇文章中,有几种方法向您展示如何实现:

从应用程序委托获取当前的视图控制器

用伪代码在您的appDelegate中:

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

2-从该视图控制器执行perfom segue(或以模态呈现或您想要的任何过渡)

在Swift 3中

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

以上假设

  1. 您不想创建一个完整的VCName实例,只需要引用它即可
  2. 您知道要引用的VC是您的根VC

暂无
暂无

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

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