实例化新 VC 后销毁当前 tabbarVC

Posted

技术标签:

【中文标题】实例化新 VC 后销毁当前 tabbarVC【英文标题】:destroy current tabbarVC after instantiate new VC 【发布时间】:2016-07-30 13:00:27 【问题描述】:

与 Instagram 非常相似,我的应用程序的主要部分有五个选项卡,其中五个 ViewController 都通过导航控制器连接到一个 tabBar 控制器。当用户点击 Logout 按钮时,我希望能够将用户发送回位于 TabBar VC 之前的 Login VC(如图所示),并“销毁”与 tabBar 控制器关联的任何内容(1 x tabbar VC, 5x navigation VC, 5x ViewControllers) 但是,我不能简单地执行“DismissViewControllerAnimated 方法”,因为在启动时,如果用户先前已登录,我将 tabBar VC 设置为初始 VC。这是通过以下方式实现的应用委托中的代码

func tryToLogin() 

    if let userUid = NSUserDefaults.standardUserDefaults().valueForKey(KEY_USER_UID) 
        print("User Exists in NSUserDefault = \(userUid)")
        updateUserGlobalVariables()

        let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let tabBarVC = storyboard.instantiateViewControllerWithIdentifier("TabBarVC") as! UITabBarController
        window?.rootViewController = tabBarVC
    

目前,当用户注销时,我“instantiateViewControllerWithIdentifier”返回到 LoginVC,因为如果用户已经登录,LoginVC 可能永远不会出现。但是,当我用另一个帐户重新登录时,我的变量中的一些数据被带回,就好像 VC/TabBarVC 永远不会被破坏一样。这就是我现在去我的 LoginVC 的方式。

func goToLoginVC() 

    let facebookManager = FBSDKLoginManager()
    facebookManager.logOut()

    do 
        try FIRAuth.auth()?.signOut()
        self.removeCurrentUserDataFromDisk()

        // Dont use dismiss as sometimes the root VC is not login VC
        let loginVC = self.storyboard?.instantiateViewControllerWithIdentifier("LoginVC") as! LoginVC
        self.presentViewController(loginVC, animated: true) 
            self.removeFromParentViewController()
        

     catch let error as NSError 
        showErrorAlert("Error", message: "\(error.localizedDescription)")
    


所以我想换句话说,我如何获得与dismissViewControllerAnimated 相同的结果 1. 实例化ViewControllerWithIdentifier 2. 销毁tabBarVC附加的遗留内容

这是我的故事板的屏幕截图

谢谢

【问题讨论】:

一种选择是更改窗口的rootViewController 并在切换后关闭以前可见的视图。这样做的“缺点”是,如果您想要平滑过渡,则必须创建自定义过渡。 您应该能够使用展开转场从任何地方返回登录 VC,但要做到这一点,您需要使用转场从登录 VC 转到选项卡栏 VC 而不是使用presentViewController 但这很简单 【参考方案1】:

如果你的 loginVC 已经嵌入了导航控制器,那么你可以在点击注销时执行类似的操作,

   UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];

UIViewController *initialViewController = [storyBoard instantiateViewControllerWithIdentifier:@"loginViewController"];


UINavigationController *nav = [storyBoard instantiateViewControllerWithIdentifier:@"navigationController"];

[nav setViewControllers:[NSArray arrayWithObjects:initialViewController, nil] animated:NO];



AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication]delegate];



CATransition* transition = [CATransition animation];
transition.duration = 0.2;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromLeft;
appDelegate.window.rootViewController = nav;

[appDelegate.window.layer addAnimation:transition forKey:nil ];

我正在我的一个项目中这样做。 navigationController 是嵌入在您的第一个 LoginViewController 中的 UINavigationController 的故事板标识符。您已标记Objective C 有问题我已经编写了obj c 代码sn-p,如果它可能有帮助。 :)

【讨论】:

我的登录 vc 没有任何导航控制器,如附图所示。感谢您的回复 您可以将其嵌入到导航控制器中以使流程更轻松!【参考方案2】:

为了实现这样的流程,我在一些容器视图控制器中使用 UITabbar 元素,并以编程方式将所有子控制器添加到标签栏。在不同选项卡选择上的视图控制器之间转换时,您可以使用转换动画,因为它与 uitabbarcoontroller 一起使用。这种方法让我将 uinavigationcontroller 嵌入到 loginviewcontroller 本身中,并始终将其设为 root。如果用户已经登录,那么在 navigationController 的 viewcontrollers 属性中添加 containerview 作为第二个元素,这将在顶部显示容器。并在注销时弹出到根视图控制器。这种方法还将帮助您将来添加或删除选项卡和控制器,而无需触摸情节提要。如果你喜欢并想要一些编码示例,请告诉我我也很想发布代码。

【讨论】:

以上是关于实例化新 VC 后销毁当前 tabbarVC的主要内容,如果未能解决你的问题,请参考以下文章

jQueryFileTree 如何清除实例、重新实例化新实例或刷新

哪个更快:清除集合或实例化新的

为每个 TableViewCell 实例化新数组

使用猫鼬崩溃在 NestJS 中实例化新文档

依赖注入概念问题:在哪里实例化新对象以保存到数据库?

在不实例化新控制器的情况下弹出查看控制器