【问题标题】:Navigating to Specific View Controllers from AppDelegate Methods从 AppDelegate 方法导航到特定的视图控制器
【发布时间】:2016-06-11 03:46:52
【问题描述】:

目前,我已经在我的 AppDelegate 中实现了这两个方法

func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: ([AnyObject]?) -> Void) -> Bool

func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool

如果用户使用 Spotlight 的搜索结果打开我的应用程序,将调用第一个,如果从 Apple Maps 打开我的应用程序(因为它是一个路由应用程序),则会调用第二个。

我的问题是,从 APPDELEGATE 转到特定 UIViewController 的最佳方式是什么(无论用户处于何种视图)?

我问的原因是因为目前我正在尝试手动导航到它,具体取决于用户可能在哪里。例如,它们可能位于模态显示的UIViewController 中(然后需要将其关闭),或者它们可能位于UINavigationController 的深处,然后应用程序需要在其中调用popToRootViewController

这样做,代码变得多毛并且似乎无法正常工作。这样做似乎也不正确,因为它非常脆弱。

【问题讨论】:

  • @vivektakrani,不完全是我要找的……那些是 viewDidFinishLaunchingWithOptions……只发生一次。我说的是其他两种委托方法(在我的帖子中提到),如果用户从 Apple Maps 或 Spotlight 进来,就会发生这种情况——这两种方法都可以在应用程序的生命周期内多次使用。

标签: ios uiviewcontroller uitabbarcontroller appdelegate nsuseractivity


【解决方案1】:

我只是想弄清楚如何实现您提到的第一种方法,并从https://www.hackingwithswift.com/read/32/4/how-to-add-core-spotlight-to-index-your-app-content 找到了一个有用的开始 他的代码是:

func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: ([AnyObject]?) -> Void) -> Bool {
    if userActivity.activityType == CSSearchableItemActionType {
        if let uniqueIdentifier = userActivity.userInfo?[CSSearchableItemActivityIdentifier] as? String {
            let splitViewController = self.window!.rootViewController as! UISplitViewController
            let navigationController = splitViewController.viewControllers[splitViewController.viewControllers.count-1] as! UINavigationController

            if let masterVC = navigationController.topViewController as? MasterViewController {
                masterVC.showTutorial(Int(uniqueIdentifier)!)
            }
        }
    }

    return true
}

我发现 self.window?.rootViewController 为? yourRootViewControllerClass 是您提出问题的一个很好的跳板。

我的代码非常基本,如下所示:

// create a storyBoard item to instantiate a viewController from. If you have multiple storyboards, use the appropriate one. I just have one so it is "Main"
let sb = UIStoryboard(name: "Main", bundle: nil)

// get the navigation controller from the window and instantiate the viewcontroller I need.
if let viewController = sb.instantiateViewControllerWithIdentifier("DetailViewController") as? ViewController,
let nav = window?.rootViewController as? UINavigationController {

    viewController.setupController(bookName)// setup the viewController however you need to. I have a method that I use (I grabbed the bookName variable from the userActivity)
    nav.pushViewController(viewController, animated: false)//use the navigation controller to present this view.

} 

这对我有用,但我必须提出警告。我的应用只有一个带有三个视图控制器(NavController->tableViewController->ViewController)的故事板。我不确定这个逻辑将如何在更复杂的应用上运行。

另一个很好的参考是:http://www.appcoda.com/core-spotlight-framework/

func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: ([AnyObject]?) -> Void) -> Bool {
    let viewController = (window?.rootViewController as! UINavigationController).viewControllers[0] as! ViewController
viewController.restoreUserActivityState(userActivity)

    return true
}

那个viewController有这个方法:

override func restoreUserActivityState(activity: NSUserActivity) {
    if activity.activityType == CSSearchableItemActionType {
        if let userInfo = activity.userInfo {
            let selectedMovie = userInfo[CSSearchableItemActivityIdentifier] as! String
            selectedMovieIndex = Int(selectedMovie.componentsSeparatedByString(".").last!)
            performSegueWithIdentifier("idSegueShowMovieDetails", sender: self)
        }
    }
}

【讨论】:

    【解决方案2】:

    我认为重新导航的好地方是在根视图控制器中订阅的事件UIApplicationDidBecomeActiveNotification(无论您使用什么)。

    当您在AppDelegate 中编写代码时 - 只需安排一个操作:用抽象数量的属性、数据参数等组装您的包裹。将其存储在某个地方(NSUserDefauils - 是个好地方,但它甚至可能是SqlCipher 实例)。并继续休息,希望能关注活动。

    UIApplicationDidBecomeActiveNotification 被触发时 - 唤醒,捕获存储的 Action 包裹,并根据 Action 属性执行您的重新导航。

    关于您的模态视图控制器。当重新导航事件到达时,他们(确切地说 - 控制器显示)应该准备好关闭他们以模态显示的所有 VC。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-27
      • 1970-01-01
      • 2017-04-11
      • 1970-01-01
      相关资源
      最近更新 更多