阻止 iOS 应用程序加载默认故事板入口点
Prevent iOS app from loading default Storyboard entry point
我正在关注 this tutorial 协调器模式,到目前为止,我已经完成了创建协调器和 运行 来自应用程序委托的 start() 的过程。但是在那个协调器上调用一个函数是行不通的,因为协调器 var 突然变成了 nil。似乎显示的初始视图控制器不是来自 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
}
}
问题仅仅是您正在查看的教程对于当前条件来说太旧了。不再有 Single View App 模板,App Delegate 不再包含 window。如果您在 Xcode 11 或 Xcode 12 中创建项目,则 window 归 场景委托 所有。实施场景委托的 willConnect
方法来完成应用委托在教程中所做的工作,一切都会 spring 栩栩如生。
防止Main.storyboard尝试自动加载的机制也发生了变化;您必须将其从 Info.plist 中的应用程序场景清单中删除(手动编辑 - 没有简单的界面)。
我正在关注 this tutorial 协调器模式,到目前为止,我已经完成了创建协调器和 运行 来自应用程序委托的 start() 的过程。但是在那个协调器上调用一个函数是行不通的,因为协调器 var 突然变成了 nil。似乎显示的初始视图控制器不是来自 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
}
}
问题仅仅是您正在查看的教程对于当前条件来说太旧了。不再有 Single View App 模板,App Delegate 不再包含 window。如果您在 Xcode 11 或 Xcode 12 中创建项目,则 window 归 场景委托 所有。实施场景委托的 willConnect
方法来完成应用委托在教程中所做的工作,一切都会 spring 栩栩如生。
防止Main.storyboard尝试自动加载的机制也发生了变化;您必须将其从 Info.plist 中的应用程序场景清单中删除(手动编辑 - 没有简单的界面)。