简体   繁体   English

防止 iOS 应用程序加载默认 Storyboard 入口点

[英]Prevent iOS app from loading default Storyboard entry point

I am following this tutorial on Coordinator pattern, and so far I have it going through creating the coordinator and running the start() from app delegate.我正在关注协调器模式的本教程,到目前为止,我已经完成了创建协调器并从应用程序委托运行 start() 的过程。 But then calling a function on that coordinator doesn't work, because suddenly the coordinator var is nil.但是随后在该协调器上调用 function 不起作用,因为突然协调器 var 为零。 It seems that the initial view controller that is shown is not the one coming from the coordinator.start() but rather the one from the storyboard entry point.似乎显示的初始视图 controller 不是来自 coordinator.start() 的视图,而是来自 storyboard 入口点的视图。 I did disable the Main in the main interface of the projects target.我确实在项目目标的主界面中禁用了 Main。

AppDelegate:应用委托:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    if let registry = DependencyResolver.shared as? DependencyRegistry {
        DependencyGraph.setup(for: registry)
    }
    
    let navController = UINavigationController()
    coordinator = MainCoordinator(navigationController: navController)
    coordinator?.start()
    
    window = UIWindow(frame: UIScreen.main.bounds)
    window?.rootViewController = navController
    window?.makeKeyAndVisible()
    return true
} 

Main coordinator:主要协调人:

class MainCoordinator: Coordinator {

    var navigationController: UINavigationController
    var childCoordinators = [Coordinator]()

    init(navigationController: UINavigationController) {
    self.navigationController = navigationController
    }

    func start() {
        let vc = InitViewController.instantiate()
        vc.coordinator = self. //!!I do hit this breakpoint
        navigationController.pushViewController(vc, animated: false)
    }
}

Init view controller (the one that's initial in the storyboard, but I'm showing it with coordinator):初始化视图 controller (storyboard 中的初始视图,但我正在与协调员一起展示它):

class InitViewController: UIViewController, Storyboarded {

    private var cameraViewModel: CameraViewModel!
    weak var coordinator: MainCoordinator?

    @IBAction func openCameraView(_ sender: Any) {
        coordinator?.openCameraView() //!!here coordinator is nil
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

Storyboarded protocol - used to get view controller out of the storyboard by id:故事板协议 - 用于通过 id 从 storyboard 中获取视图 controller:

protocol Storyboarded {
    static func instantiate() -> Self
}


extension Storyboarded where Self: UIViewController {
    static func instantiate() -> Self {
        let fullName = NSStringFromClass(self)
        let className = fullName.components(separatedBy: ".")[1]
        let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
        let leController = storyboard.instantiateViewController(withIdentifier: className) as! Self
        return leController
    }
}

The problem is merely that the tutorial you're looking at is too old for current conditions.问题仅仅是您正在查看的教程对于当前条件来说太旧了。 There is no Single View App template any more, and the App Delegate no longer contains the window.不再有 Single View App 模板,App Delegate 不再包含 window。 If you create a project in Xcode 11 or Xcode 12, the window is owned by the scene delegate .如果您在 Xcode 11 或 Xcode 12 中创建项目,则 window 归场景委托所有。 Implement the scene delegate's willConnect method to do the work that the app delegate was doing in the tutorial, and everything will spring to life.实现场景代理的willConnect方法来完成应用程序代理在教程中所做的工作,一切都会 spring 栩栩如生。

Also the mechanism for preventing Main.storyboard from trying to load automatically has changed;防止Main.storyboard尝试自动加载的机制也发生了变化; you have to remove it from Application Scene Manifest in the Info.plist (editing by hand — there is no simple interface).您必须将其从Info.plist中的 Application Scene Manifest 中删除(手动编辑 - 没有简单的界面)。

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

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