如何通过以编程方式将根(选项卡 ViewController)从子选项卡设置为未实例化的不同 VC
Posted
技术标签:
【中文标题】如何通过以编程方式将根(选项卡 ViewController)从子选项卡设置为未实例化的不同 VC【英文标题】:How to unwind through progrmmatically set rootVC (tabViewController) from child tab to different VC that was not instantiated 【发布时间】:2020-07-11 18:00:21 【问题描述】:Swift 5 / xCode 11.5
当应用启动时,App Delegate 将检查用户手机上保存的身份验证令牌。如果它不存在,它将显示什么是 InitialViewController(实例化它,将其设置为 rootViewController,并在窗口中显示它)。如果存在令牌,它将实例化并将 MainTabController 设置为 rootVC 并显示它。层次结构如下所示:
RegisterViewController (之间没有导航控制器)InitialViewController LoginViewController 如果成功登录或注册,上述所有控制器都会推送到 MainTabController,假设手机上不存在用户的身份验证令牌(这些“视图之间没有导航控制器” ',只是推送/关闭。)。MainTabController 具有三个选项卡,它们是通过 NavControllers 连接的 UIViewControllers。
由于 rootVC 是在 AppDelegate 中以编程方式通过 Window 对象实例化和显示的,因此 InitialViewController 无法从 MainTabController 上的选项卡(已设置作为 rootVC),假设用户确实有一个保存的身份验证令牌。
我的解决方法是删除身份验证令牌,然后在 AppDelegate 中调用一个函数,该函数将切换 rootViewController 并让 Window 显示它(返回到 InitialViewController)。我担心所有其他被实例化的 VC,这可能会导致内存堆积。当我这样做时,是否所有 MainTabController 的 子级都被解除分配?这是注销操作和切换 rootVC 的代码:
退出
@IBAction func logout(_ sender: Any)
UserServices.logoutUser()
responseResult in
if responseResult == .Success
CommonUtils.clearAuthToken()
CommonUtils.clearAllUserDefaultData()
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.switchRootViewController()
else
self.showAlert(title: "Error", message: responseResult.rawValue)
AppDelegate 中的 switchRootViewController
func switchRootViewController() -> Void
let rootController = UIStoryboard(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "InitialViewController")
self.window?.rootViewController = rootController
我已经用 unwind segue 尝试过(内部注销操作)
let initialController = UIStoryboard(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "InitialViewController")
initialController.addChild(self) // self is tab VC I'm trying to unwind from
let children = initialController.children
self.performSegue(withIdentifier: "unwindToHomeScreen", sender: self)
InitialViewControllers 展开 segue 代码
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool
return true
override func canPerformUnwindSegueAction(_ action: Selector, from fromViewController: UIViewController, sender: Any?) -> Bool
return true
@IBAction func unwindToInitialViewController(sender: UIStoryboardSegue)
我认为这种展开不起作用,因为 InitialViewController 不存在引用。我会显示布局图片,但在产品发布之前,该项目本质上是秘密的......如果您需要更多信息或者我在问题描述中不清楚,请告诉我。
【问题讨论】:
【参考方案1】:如果你试试这个:
func ToSomeScreen()
let homeViewController = storyboard?.instantiateViewController(identifier: "Storyboard ID") as? ScreenCustummerViewController //file name for next screen
view.window?.rootViewController = homeViewController
view.window?.makeKeyAndVisible()
【讨论】:
我当前用于切换 rootVC 的实现是有效的,我只是问我是否会造成内存泄漏,因为 MainTabController 的所有子代都没有被破坏。文档还说makeKeyAndVisible()
窗口将: > 将其放置在同一级别或更低级别的所有其他窗口的前面,我需要将它们全部解除或取消分配。或者通过 MainTabController 找到一些放松的方法。以上是关于如何通过以编程方式将根(选项卡 ViewController)从子选项卡设置为未实例化的不同 VC的主要内容,如果未能解决你的问题,请参考以下文章
Vb.net 如何以编程方式选择选项卡控件中的最后一个选项卡
如何以编程方式切换到 UITabBarController 中的另一个选项卡?