xcode 从 App Delegate (Swift) 调用 ViewControllers 方法或 Segue
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27966305/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Call ViewControllers Method or Segue from App Delegate (Swift)
提问by Moss Palmer
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 调用函数,但是每当它们引用自己来更新任何细节或执行 segue 时,应用程序就会崩溃。
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; the full solution for me was to do the following:
对于有此问题的其他人。遵循 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);
}
}
this also allows me to make calls on functions in the view such as in the original example e.g.
这也允许我调用视图中的函数,例如在原始示例中
rootViewController.handleMessageNotificaion(messageID);
or
或者
rootViewController.messageView.reloadData();
采纳答案by gabuh
You are creating an instance of a new 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. I think that's not going to work...
您正在创建一个 new 的实例ViewController
。并且您正在尝试在该 ViewController 上调用一个函数,该函数试图执行 segue,而 ViewController 甚至没有显示。我认为这行不通...
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.
如果要从详细信息视图执行转场,则必须访问当前实例化的视图控制器并从中执行转场。
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- 从该视图控制器执行转场(或以模态呈现或您想要的任何过渡)
回答by Dave G
In Swift 3:
在 Swift 3 中:
guard let rvc = self.window?.rootViewController as? VCName else { return }
rvc.methodInYourVC()
The above assumes
以上假设
- That you don't want to create a whole new instance of VCName, just want a reference to it
- That you know the VC you want to reference is your root VC
- 你不想创建一个全新的 VCName 实例,只想引用它
- 您知道要引用的 VC 是您的根 VC