从导航控制器到选项卡控制器视图
Posted
技术标签:
【中文标题】从导航控制器到选项卡控制器视图【英文标题】:Going from Navigation controller to tab controller views 【发布时间】:2018-08-17 11:59:26 【问题描述】:我正在开发 ios 应用程序。并且它有一些客户的设计限制。所以看起来我必须在不同数量的 Viewcontrollers 上同时使用导航控制器和选项卡控制器。
我可以将我的观点分为 2 类。
-
注册/登录视图(这是应用首次启动时的入口点)
MainView -> 一旦用户登录,这将成为入口点
现在类别 1 正在使用 NavigationView 控制器。其中 Category2 使用的是 Tab bar 控制器。
我想要的情况 1: 我想要当用户安装我的应用程序时,他会被带到具有导航视图的登录视图。现在,如果他还没有帐户,他将转到“创建新帐户”,这是导航视图的第二个场景。现在成功创建帐户后,他需要关闭所有其他导航视图控制器并需要跳转到将成为 Tabbar 视图控制器的 MainView。
案例2:假设用户在登录后关闭了我的应用程序,当他再次打开它时,现在的入口点将是具有标签栏视图控制器的Mainview。现在我知道我需要在 App 委托方法中执行此操作,但如何操作?
我正在这样做,它看起来像工作。但我没有得到底部标签。为什么会这样?
class ViewSwitcher
static func updateRootViewController()
let status = UserDefaults.standard.bool(forKey: KeyConstants.IS_USER_LOGGEDIN)
var rootViewController : UIViewController?
#if DEBUG
print(status)
#endif
if (status == true)
let mainStoryBoard = UIStoryboard(name: "Main", bundle: nil)
let mainTabBarController = mainStoryBoard.instantiateViewController(withIdentifier: "idTab1VC") as! Tab1VC
rootViewController = mainTabBarController
else
let mainStoryBoard = UIStoryboard(name: "Main", bundle: nil)
let signInViewController = mainStoryBoard.instantiateViewController(withIdentifier: "idLoginVC") as! LoginVC
rootViewController = signInViewController
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.window?.rootViewController = rootViewController
知道如何处理这些情况吗?如何通过关闭所有视图控制器树以编程方式导航?
【问题讨论】:
您必须将某种标志或用户数据存储到任何永久存储中,例如 UserDefaults、SQLLite、CoreData 以识别用户已登录。然后您必须要求在 AppDelegatedidFinishWithLaunchingOptions
中放置一个条件在窗口中设置应用程序 rootViewController。
告诉我如何设置应用程序 rootViewController。请告诉我这个
在 AppDelegateself.window.rootViewController =
中分配您的登录 navigationController 根目录,与 tabbarcontroller 相同。
@PratikSodha 请检查更新后的答案
@android teem Great..
【参考方案1】:
我一直在为我的应用程序使用相同的过程。
使用此代码更改 Case2 中的 rootViewController
var window: UIWindow?
var tabBarController : UITabBarController?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
// Tabbar controller
let storyBoard = UIStoryboard.init(name: "Main", bundle: Bundle.main)
let tab1 = UINavigationController.init(rootViewController: storyBoard.instantiateViewController(withIdentifier: "tab1"))
tab1 = UITabBarItem.init(title: "Title 1", image: UIImage(named : "Image.png") , tag: 0)
let tab2 = UINavigationController.init(rootViewController: storyBoard.instantiateViewController(withIdentifier: "tab2"))
tab2 = UITabBarItem.init(title: "Title 2", image: UIImage(named : "Image.png") , tag: 1)
// Navigation controller or Login view controller
let nav1 = UINavigationController.init(rootViewController: storyBoard.instantiateViewController(withIdentifier: "nav1"))
tabBarController = UITabBarController.init()
tabBarController?.delegate = self
tabBarController?.selectedIndex = 0
tabBarController?.viewControllers = [tab1,tab2]
// The Bool value which you have to set as True after a user logged in
if UserDefaults.standard.bool(forKey: "LoggedIn")
print("Tabbar")
self.window?.rootViewController = self.tabBarController
else
print("Navigation")
self.window?.rootViewController = nav1
return true
在此之前或之后,您必须编写与用户在您的loginViewController
中单击登录相同的代码,在您的情况下是 Case1
func loginClicked()
UserDefaults.standard.set(true, forKey: "LoggedIn")
DispatchQueue.main.async
let appdelegate = UIApplication.shared.delegate as! AppDelegate
// Same as above code and replace self with appDelegate without if condition and at last
appdelegate.window?.rootViewController = appdelegate.tabBarController
用户退出后
DispatchQueue.main.async
UserDefaults.standard.set(false, forKey: "LoggedIn")
let appdelegate = UIApplication.shared.delegate as! AppDelegate
let story = UIStoryboard.init(name: "Main", bundle: Bundle.main)
let nav1 = UINavigationController.init(rootViewController: storyBoard.instantiateViewController(withIdentifier: "nav1"))
appdelegate.window?.rootViewController = companyNavigation
【讨论】:
【参考方案2】:在应用程序委托 didFinishWithLaunchingOptions 中使用以下代码,直接用于主视图。这里 uid 表示存储的值是否检查用户是否处于活动状态。
let storyboard = UIStoryboard(name: "Main", bundle: nil)
if let user_id = UserDefaults.standard.value(forKey: "uid")
let homeViewController = storyboard.instantiateViewController(withIdentifier: "HomeTabBarCtrlr") as! UITabBarController
let nav = UINavigationController(rootViewController: homeViewController)
self.window!.rootViewController = nav
else
注册/登录视图
【讨论】:
【参考方案3】:逐步解决此问题的方法是:
-
检查用户是否登录。为此使用 UserDefaults。
如果用户未登录,请将 LoginVC 设置为 rootVC。
登录时在 UserDefault 中保存一个密钥以表示用户已登录。
下次用户打开应用时检查密钥,如果用户已登录,请将 TabBarVC 设置为 rootViewController。
在注销时,清除密钥。
上面的示例代码将是:
AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
...........
//Check for user login and set rootViewController.
if UserDefaults.standard.bool(forKey: "login")
self.window?.rootViewController = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController()
else
self.window?.rootViewController = UIStoryboard(name: "Login", bundle: nil).instantiateInitialViewController()
return true
登录成功时
func loginUser()
...
if userLoginSuccess
UserDefaults.standard.set(true, forKey: "login")
注销时
UserDefaults.standard.set(false, forKey: "login")
【讨论】:
【参考方案4】:就像您知道您想在 Appdelgate 中执行此操作一样。
当用户登录成功时,您必须在 userdefault 中存储一个标志。 在应用程序委托中,您必须检查是否设置了此标志。如果已设置,则使用初始视图控制器调用 moveToLoginWindow() 创建导航视图控制器。 或者如果没有,则创建标签栏视图控制器调用 movetoTabBarController()。
func moveToLoginWindow() -> Void
if let rootController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "LoginVC") as? LoginVC
let navigationController = UINavigationController.init(rootViewController: rootController)
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()
func movetoTabBarController() -> Void
let nav2 = UINavigationController()
let second = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "secondViewController") as? SecureNotesVC
nav2.viewControllers = [second!]
nav2.tabBarItem = UITabBarItem.init(title: "Titel 2", image: UIImage.init(named: "2.png"), selectedImage: UIImage.init(named: "2_sel.png"))
let nav3 = UINavigationController()
let third = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "thirdviewController") as? FormFillsVC
nav3.viewControllers = [third!]
nav3.tabBarItem = UITabBarItem.init(title: "Titel 2", image: UIImage.init(named: "3.png"), selectedImage: UIImage.init(named: "3_sel.png"))
let nav4 = UINavigationController()
let fourth = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "fourthviewContoller") as? SettingsVC
nav4.viewControllers = [fourth!]
nav4.tabBarItem = UITabBarItem.init(title: "4", image: UIImage.init(named: "4.png"), selectedImage: UIImage.init(named: "4_sel.png"))
if #available(iOS 11.0, *)
nav2.navigationBar.prefersLargeTitles = true
nav3.navigationBar.prefersLargeTitles = true
nav4.navigationBar.prefersLargeTitles = true
let tabBarController = UITabBarController()
tabBarController.viewControllers = [ nav2,nav3, nav4,nav5]
self.window!.rootViewController = tabBarController;
【讨论】:
以上是关于从导航控制器到选项卡控制器视图的主要内容,如果未能解决你的问题,请参考以下文章