目前,我的应用主界面如下:
Root View Controller 本身没有任何值,需要确定要显示哪个控制器。逻辑相当复杂,但这对这个问题并不重要。最简单的类似示例如下所示:
override func viewDidAppear(_ animated: Bool) {
var controller: UIViewController?
if !userIsAuthenticated {
let storyboard = UIStoryboard(name: "Login", bundle: nil)
controller = storyboard.instantiateViewController(withIdentifier: "loginController")
}
else if systemHasAlert {
let storyboard = UIStoryboard(name: "Alert", bundle: nil)
controller = storyboard.instantiateViewController(withIdentifier: "alertController")
}
else {
let storyboard = UIStoryboard(name: "Landing", bundle: nil)
controller = storyboard.instantiateViewController(withIdentifier: "defaultLandingPage")
}
guard let _controller = controller else {
return
}
navigationController?.pushViewController(_controller, animated: true )
}
(逻辑本身是象征性的,不是那么简单。但这足以传达这个想法。)
该控制器还为应用程序状态更改提供了一个稳定的“返回点”。例如,在用户成功登录后,我要做的就是:
AppDelegate.shared.navigationController?.popToRootViewController(animated: false)
这将导致重新评估 Root View Controller 中的条件,并且应用程序导航到另一个视图
通常这可以,但是我不喜欢3件事:
viewDidAppear
替换为viewWillAppear
来解决此问题,但在那种情况下,导航似乎根本没有发生那么有没有更好的选择来提供这样的“根级别”协调器?还是根视图协调器是正确的选择,我应该担心正确地设置样式,而不是消除它?
预先感谢
答案 0 :(得分:0)
我不确定我是否理解正确,但是似乎根本不需要根视图控制器,但需要显示三个控制器之一(即“登录”,“警告”和“着陆”)。
在这种情况下,确实似乎视图控制器中的viewDidAppear
方法不是处理此逻辑的最佳位置。最简单的方法是在AppDelegate
方法中的application(_:didFinishLaunchingWithOptions:)
类内处理逻辑。您的实现可能如下所示:
var window: UIWindow?
...
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Initialize navigation controller without root view controller
let navigationVC = UINavigationController()
window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()
// Set navigationVC as a root view controller in your application
// Now it would ignore your storyboard.
window?.rootViewController = navigationVC
var controller: UIViewController?
if !userIsAuthenticated {
let storyboard = UIStoryboard(name: "Login", bundle: nil)
controller = storyboard.instantiateViewController(withIdentifier: "loginController")
}
else if systemHasAlert {
let storyboard = UIStoryboard(name: "Alert", bundle: nil)
controller = storyboard.instantiateViewController(withIdentifier: "alertController")
}
else {
let storyboard = UIStoryboard(name: "Landing", bundle: nil)
controller = storyboard.instantiateViewController(withIdentifier: "defaultLandingPage")
}
if let controller = controller {
navigationVC.pushViewController(controller, animated: false)
}
return true
}
P.S。:请记住,上述实现会覆盖情节提要文件中定义的应用程序的入口点。
P.P.S::您在原始帖子中提到了“协调员”。上面显示的方法是最简单的方法,但可能不是最好的方法。对于更复杂的逻辑,您可能确实需要实现协调器。尽管许多iOS开发人员都熟悉协调器概念,但在iOS社区中没有唯一的实现方法。因此,我将只讨论讨论协调器的几个链接,希望对您有所帮助: