从 App Delegate 调用 ViewControllers 方法或 Segue (Swift)
Call ViewControllers Method or Segue from App Delegate (Swift)
我创建了一个使用情节提要的应用程序,并成功创建了一个表格视图和详细信息页面,一切正常。
我希望这样可以将滑动 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 工作正常但 performSegue 失败(致命错误:在展开可选值时意外发现 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();
您正在创建新 ViewController
的实例。当 ViewController 甚至没有显示时,您正试图在 ViewController 上调用一个函数,该函数试图执行一个 segue。我认为这行不通...
如果您想从详细视图执行转场,您必须访问当前实例化的视图控制器并从中执行转场。
如果您想知道如何获取正在显示的 UIViewController 的实例,在此 post 中有几种方法可以向您展示如何做到这一点:
Get the current view controller from the app delegate
在伪代码中,在您的 appDelegate 中:
1- 获取当前 UIViewController 实例(不是新实例)
2- 从该视图控制器执行 segue(或模态呈现或您想要的任何过渡)
在Swift 3:
guard let rvc = self.window?.rootViewController as? VCName else { return }
rvc.methodInYourVC()
以上假设
- 您不想创建 VCName 的全新实例,只想引用它
- 您知道要引用的 VC 是您的根 VC
我创建了一个使用情节提要的应用程序,并成功创建了一个表格视图和详细信息页面,一切正常。
我希望这样可以将滑动 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 工作正常但 performSegue 失败(致命错误:在展开可选值时意外发现 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();
您正在创建新 ViewController
的实例。当 ViewController 甚至没有显示时,您正试图在 ViewController 上调用一个函数,该函数试图执行一个 segue。我认为这行不通...
如果您想从详细视图执行转场,您必须访问当前实例化的视图控制器并从中执行转场。
如果您想知道如何获取正在显示的 UIViewController 的实例,在此 post 中有几种方法可以向您展示如何做到这一点:
Get the current view controller from the app delegate
在伪代码中,在您的 appDelegate 中:
1- 获取当前 UIViewController 实例(不是新实例)
2- 从该视图控制器执行 segue(或模态呈现或您想要的任何过渡)
在Swift 3:
guard let rvc = self.window?.rootViewController as? VCName else { return }
rvc.methodInYourVC()
以上假设
- 您不想创建 VCName 的全新实例,只想引用它
- 您知道要引用的 VC 是您的根 VC