Swift - 通过索引号引用 navigationController 中的 viewController

Swift - Reference viewControllers in navigationController by index number

这段代码说明了我的问题:

对于具有 2 个屏幕的简单应用程序,rootViewController 和一个 TableViewControllerrootVC 将位于 navigationController 中的索引 [0],接下来的视图将索引增加 1

import UIKit
import CoreData

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?


    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

        let navController = self.window?.rootViewController as! UINavigationController
        let firstViewController = navController.viewControllers[0] as! firstViewController
        firstViewController.managedObjectContext = self.managedObjectContext

        return true
    }

现在我试图将 managedObjectContextappDelegate 传递到 rootViewController 后面的 ViewControllers:

中心视图是 rootViewController,我想将 managedObjectContext 传递到其上方和下方的屏幕。

我尝试将它从 appDelegate 传递到 rootViewController,然后从 rootViewController 传递到下一个视图,但它不起作用。

谁能告诉我如何知道同一视图后面的视图的索引号?谢谢!

Now I am trying to pass managedObjectContext from appDelegate to the ViewControllers behind the rootViewController

你不能。整个想法毫无意义。在应用程序委托中的代码运行时,那些视图控制器还不存在。故事板只是一组 指令 用于制作视图控制器的未来 实例 ;在 application:didFinishLaunchingWithOptions: 期间没有这样的实例 — 除了您在代码中明确创建的第一个实例。

相反,这些视图控制器中的每一个都需要在它们自己的代码(例如它们的 viewDidLoad)中 从应用委托中获取 managedObjectContext managedObjectContext .这是他们都可以轻松做到的事情,因为应用程序委托有一个 managedObjectContext 属性,他们都可以 看到 属性 因为他们可以所有人都看到应用程序委托(因为它是共享应用程序的delegate)。

我不太同意上面的答案,因为从你的视图控制器或任何其他对象获取你的应用委托只是为了获取它的存储属性被认为是一种不好的做法。

你可以做的是使用依赖注入的概念在你的视图控制器中传递 managedObjectContext 当你使用 prepareForSegue 方法向下移动你的视图层次结构时,如果你正在执行一个 segue 或者将它分配给下一个视图控制器,如果您正在以编程方式实例化并将其推送到导航堆栈上。

    // App delegate: - didFinishLaunchingWithOptions
    let navCon = window?.rootViewController as? UINavigationController
    let rootVC = navCon?.viewControllers.first as? firstViewController
    rootVC?.managedObjectContext = managedObjectContext

    // FirstViewController: - Using segue
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
      guard let identifier = segue.identifier else { return }
      switch identifier {
      case "SecondView":
        let navCon = segue.destinationViewController as? UINavigationController
        let controller = navCon?.topViewController as? SecondViewController
        controller?.managedObjectContext = self.managedObjectContext
      default:
        break
      }
    }

    // FirstViewController: - Pushing programmatically 
    let controller = SecondViewController()
    controller.managedObjectContext = self.managedObjectContext
    navigationController?.pushViewController(controller, animated: true)