【问题标题】:Prevent iOS app from loading default Storyboard entry point阻止 iOS 应用加载默认 Storyboard 入口点
【发布时间】:2021-05-31 08:47:29
【问题描述】:

我在 Coordinator 模式上关注 this tutorial,到目前为止,我已经完成了创建协调器并从应用程序委托运行 start()。但是随后在该协调器上调用函数不起作用,因为突然协调器 var 为零。似乎显示的初始视图控制器不是来自 coordinator.start() 的那个,而是来自故事板入口点的那个。我确实在项目目标的主界面中禁用了 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
} 

主要协调员:

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)
    }
}

初始化视图控制器(故事板中最初的那个,但我用协调器展示它):

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()
    }
}

情节提要协议 - 用于通过 id 将视图控制器从情节提要中取出:

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
    }
}

【问题讨论】:

    标签: ios swift xcode coordinator-pattern


    【解决方案1】:

    问题仅仅是您正在查看的教程对于当前条件来说太旧了。不再有 Single View App 模板,App Delegate 不再包含窗口。如果您在 Xcode 11 或 Xcode 12 中创建项目,则该窗口归 scene delegate 所有。实现场景代理的willConnect 方法来完成应用程序代理在教程中所做的工作,一切都会变得栩栩如生。

    防止 Main.storyboard 尝试自动加载的机制也已更改;您必须将其从 Info.plist 中的 Application Scene Manifest 中删除(手动编辑 - 没有简单的界面)。

    【讨论】:

    • 我已经编写了教程项目的现代化版本,因此您可以下载它并从那里开始:github.com/mattneub/PaulHudsonCoordinatorDemo - 它开箱即用!
    • 谢谢!我在某些时候想它必须是场景,因为教程中没有它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-04
    • 1970-01-01
    • 1970-01-01
    • 2015-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多