什么时候需要切换 rootViewController
when need to switch the rootViewController
我一直在做一个 Swift 项目,我有两个视图控制器,登录视图控制器和主页视图控制器。当用户启动应用程序时,如果用户未登录,我想显示登录视图控制器,另一方面,如果用户已登录,我想显示主视图控制器。
所以流程会是这样的。
用户未登录时,显示
- 登录视图控制器
- HomeViewController
当用户已经登录时,显示
- HomeViewController
在场景委托中,我写了
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let scene = (scene as? UIWindowScene) else { return }
window = UIWindow(frame: scene.coordinateSpace.bounds)
window?.windowScene = scene
window?.rootViewController = HomeViewController() or LoginViewController() depending on the user's login status
window?.makeKeyAndVisible()
}
我想知道我是否应该将 HomeViewController 应用为 rootviewcontroller 而不管用户的登录状态(并且可能在用户未登录时在 homeVC 上显示 loginVC),或者我应该切换根据用户的登录状态查看控制器。
那么,在这种情况下,切换 root 的意义何在viewcontroller?为什么要(或不重要)切换根视图控制器?
当我将视图控制器应用到根目录时,有什么我应该考虑的吗viewcontroller 属性?
我觉得还可以有其他情况,比如RootVC就是一个容器ViewContoller,由HomeVC和LoginVC组成。
示例)
final class RootVC: UIViewController {
private let loginVC = LoginVC()
private let homeVC = HomeVC()
override func viewDidLoad() {
super.viewDidLoad()
addChild(homeVC)
view.addSubview(homeVC.view)
addChild(loginVC)
view.addSubview(loginVC.view)
}
func showVC() {
if isLogin {
homeVC.hide()
loginVC.show()
} else {
reverse()
}
}
}
// SceneDelegate.swift
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
guard let _ = (scene as? UIWindowScene) else { return }
// if user is logged in before
if let loggedUsername = UserDefaults.standard.string(forKey: "username") {
window?.rootViewController = HomeViewController()
} else {
// if user isn't logged in
window?.rootViewController = LoginViewController()
}
}
大家好,我有一个关于在 SceneDelegate
中设置 RootViewController 的想法。首先我们需要在 SceneDelegate
class 中创建方法 setViewController
和变量 currentScene
请随意参考下面的代码。
根据您的示例 HomeViewController,两个不同的 viewcontroller,LoginViewController
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
var currentScene: UIScene?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let _ = (scene as? UIWindowScene) else { return }
currentScene = scene
if UserDefaults.standard.bool(forKey: "isLoggedIn") == true{
self.setRootViewController(LoginViewController())
}else{
self.setRootViewController(HomeViewController())
}
}
func setRootViewController(_ viewController: UIViewController){
guard let scene = (currentScene as? UIWindowScene) else { return }
window = UIWindow(frame: scene.coordinateSpace.bounds)
window?.windowScene = scene
window?.rootViewController = viewController
window?.makeKeyAndVisible()
}
}
class ButtonViewController: UIViewController {
lazy var button: UIButton! = {
let button = UIButton()
button.translatesAutoresizingMaskIntoConstraints = false
button.backgroundColor = .darkGray
button.setTitleColor(.white, for: .normal)
button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
button.tag = 1
button.setTitle("Tap", for: .normal)
return button
}()
override func loadView() {
super.loadView()
self.view.backgroundColor = .white
setConstraint()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
}
func setConstraint(){
self.view.addSubview(self.button)
NSLayoutConstraint.activate([
self.button.heightAnchor.constraint(equalToConstant: 60),
self.button.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width * 0.66),
self.button.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
self.button.centerYAnchor.constraint(equalTo: self.view.centerYAnchor),
])
}
@objc func buttonAction(){ }
}
class HomeViewController: ButtonViewController{
override func loadView() {
super.loadView()
self.view.backgroundColor = .red
self.button.setTitle(String(describing: HomeViewController.self), for: .normal)
}
override func buttonAction() {
let sceneDelegate = UIApplication.shared.connectedScenes.first?.delegate as! SceneDelegate
sceneDelegate.setRootViewController(LoginViewController())
}
}
class LoginViewController: ButtonViewController{
override func loadView() {
super.loadView()
self.view.backgroundColor = .green
self.button.setTitle(String(describing: LoginViewController.self), for: .normal)
}
override func buttonAction() {
let sceneDelegate = UIApplication.shared.connectedScenes.first?.delegate as! SceneDelegate
sceneDelegate.setRootViewController(HomeViewController())
}
}
如果单击按钮视图控制器可以更改为rootViewController。
输出:
我一直在做一个 Swift 项目,我有两个视图控制器,登录视图控制器和主页视图控制器。当用户启动应用程序时,如果用户未登录,我想显示登录视图控制器,另一方面,如果用户已登录,我想显示主视图控制器。
所以流程会是这样的。
用户未登录时,显示
- 登录视图控制器
- HomeViewController
当用户已经登录时,显示
- HomeViewController
在场景委托中,我写了
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let scene = (scene as? UIWindowScene) else { return }
window = UIWindow(frame: scene.coordinateSpace.bounds)
window?.windowScene = scene
window?.rootViewController = HomeViewController() or LoginViewController() depending on the user's login status
window?.makeKeyAndVisible()
}
我想知道我是否应该将 HomeViewController 应用为 rootviewcontroller 而不管用户的登录状态(并且可能在用户未登录时在 homeVC 上显示 loginVC),或者我应该切换根据用户的登录状态查看控制器。
那么,在这种情况下,切换 root 的意义何在viewcontroller?为什么要(或不重要)切换根视图控制器?
当我将视图控制器应用到根目录时,有什么我应该考虑的吗viewcontroller 属性?
我觉得还可以有其他情况,比如RootVC就是一个容器ViewContoller,由HomeVC和LoginVC组成。 示例)
final class RootVC: UIViewController {
private let loginVC = LoginVC()
private let homeVC = HomeVC()
override func viewDidLoad() {
super.viewDidLoad()
addChild(homeVC)
view.addSubview(homeVC.view)
addChild(loginVC)
view.addSubview(loginVC.view)
}
func showVC() {
if isLogin {
homeVC.hide()
loginVC.show()
} else {
reverse()
}
}
}
// SceneDelegate.swift
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
guard let _ = (scene as? UIWindowScene) else { return }
// if user is logged in before
if let loggedUsername = UserDefaults.standard.string(forKey: "username") {
window?.rootViewController = HomeViewController()
} else {
// if user isn't logged in
window?.rootViewController = LoginViewController()
}
}
大家好,我有一个关于在 SceneDelegate
中设置 RootViewController 的想法。首先我们需要在 SceneDelegate
class 中创建方法 setViewController
和变量 currentScene
请随意参考下面的代码。
根据您的示例 HomeViewController,两个不同的 viewcontroller,LoginViewController
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
var currentScene: UIScene?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let _ = (scene as? UIWindowScene) else { return }
currentScene = scene
if UserDefaults.standard.bool(forKey: "isLoggedIn") == true{
self.setRootViewController(LoginViewController())
}else{
self.setRootViewController(HomeViewController())
}
}
func setRootViewController(_ viewController: UIViewController){
guard let scene = (currentScene as? UIWindowScene) else { return }
window = UIWindow(frame: scene.coordinateSpace.bounds)
window?.windowScene = scene
window?.rootViewController = viewController
window?.makeKeyAndVisible()
}
}
class ButtonViewController: UIViewController {
lazy var button: UIButton! = {
let button = UIButton()
button.translatesAutoresizingMaskIntoConstraints = false
button.backgroundColor = .darkGray
button.setTitleColor(.white, for: .normal)
button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
button.tag = 1
button.setTitle("Tap", for: .normal)
return button
}()
override func loadView() {
super.loadView()
self.view.backgroundColor = .white
setConstraint()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
}
func setConstraint(){
self.view.addSubview(self.button)
NSLayoutConstraint.activate([
self.button.heightAnchor.constraint(equalToConstant: 60),
self.button.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width * 0.66),
self.button.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
self.button.centerYAnchor.constraint(equalTo: self.view.centerYAnchor),
])
}
@objc func buttonAction(){ }
}
class HomeViewController: ButtonViewController{
override func loadView() {
super.loadView()
self.view.backgroundColor = .red
self.button.setTitle(String(describing: HomeViewController.self), for: .normal)
}
override func buttonAction() {
let sceneDelegate = UIApplication.shared.connectedScenes.first?.delegate as! SceneDelegate
sceneDelegate.setRootViewController(LoginViewController())
}
}
class LoginViewController: ButtonViewController{
override func loadView() {
super.loadView()
self.view.backgroundColor = .green
self.button.setTitle(String(describing: LoginViewController.self), for: .normal)
}
override func buttonAction() {
let sceneDelegate = UIApplication.shared.connectedScenes.first?.delegate as! SceneDelegate
sceneDelegate.setRootViewController(HomeViewController())
}
}
如果单击按钮视图控制器可以更改为rootViewController。 输出: