【问题标题】:Changing root view controller in the background在后台更改根视图控制器
【发布时间】:2015-12-05 00:04:32
【问题描述】:

我有以下视图控制器堆栈。

首先,我的应用会显示一个应用游览页面。 (比如说TourViewController - 超级类是UIViewController)。在AppDelegate 中添加了这个控制器作为rootviewcontroller。

self.window.rootViewController = tourViewController;

然后在游览页面中,如果用户点击“登录”按钮,我将展示第二个视图控制器(比如 LoginViewController - 超类是 UIViewController)。

UINavigationController *loginNavigationController = [[UINavigationController alloc] initWithRootViewController:self.loginViewController];
[self presentViewController:loginNavigationController animated:YES completion:nil];

成功登录后,我需要退出第二个视图控制器 (LoginViewController) 并希望显示基于标签栏的视图以满足进一步的需求。

我在登录成功方法中尝试了这段代码。

[self dismissViewControllerAnimated:YES completion:^{

        TabBarViewController *tabController = [[TabBarViewController alloc] init];

        [self presentViewController:tabController animated:NO completion:nil];

        AppDelegate *applicationDelegate = [[UIApplication sharedApplication] delegate];
        applicationDelegate.window.rootViewController = tabController;

    }];

问题:

  • 当我在LoginViewController 中时,我的堆栈中有两个视图控制器。所以即使我辞掉了LoginViewController,另一个(TourViewController)仍然在屏幕上。

  • 如果我尝试了上面的代码,tab bat 控制器被成功添加为根视图控制器。但是,当LoginViewController 辞职时,背景被TourViewController 填充

我需要的是,当我辞职LoginViewController时,背景视图应该是标签栏控制器而不是TourViewController

需要帮助!!

【问题讨论】:

  • 简单的解决方案是,将您的loginviewcontroller 分配为根视图而不是显示它,然后当您成功登录时将您的tabbarcontroller 分配为根视图。

标签: ios uitabbarcontroller dismiss rootview


【解决方案1】:

你可以在AppDelegate而不是loginNavigationController的成功方法中更改根视图控制器更好你可以这样做

AppDelegate.h

 #import <UIKit/UIKit.h>
 #import "TabControllerViewController.h"

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

- (void)showTabController;  //add this method call from on success method of log in completion 
@end

AppDelegate.m

- (void)showTabController;
 {
   TabControllerViewController *tabController =    [[TabControllerViewController alloc]  initWithNibName:@"TabControllerViewController" bundle:nil];
  self.window.rootViewController = tabController;
 [self.window makeKeyAndVisible];
}

loginNavigationController.m

[self dismissViewControllerAnimated:YES completion:^{

    //TabBarViewController *tabController = [[TabBarViewController alloc] init];

  //  [self presentViewController:tabController animated:NO completion:nil]; //no nee to present 

    AppDelegate *applicationDelegate = [[UIApplication sharedApplication] delegate];
     [applicationDelegate showTabController]; //there is no need to create a tab bar in loginview controller, create it in root view controller 
    //applicationDelegate.window.rootViewController = tabController;

}];

注意:以上内容未经测试,请尝试一次

编辑 1

你可以做到这一点,但动画不同, 形成这个answer 你可以通过做一些动画来切换到第二个窗口

AppDelegate.h

#import <UIKit/UIKit.h>
#import "TabViewController.h"
#import "LoginViewController.h"

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window; //holds initial window, holds tour and login controller
@property (strong, nonatomic) UIWindow *tabWindow; //holds only tab controller 
//..other code below is my test 
@property (strong, nonatomic) TabViewController *tabViewController;
@property (strong, nonatomic) LoginViewController *loginController;
- (void)showTabController;
@end

AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{
   _tabWindow = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
   _window    = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];

   // Override point for customization after application launch.
   _loginController = [[LoginViewController alloc]initWithNibName:@"LoginViewController" bundle:nil];
   _tabViewController = [[TabViewController alloc] initWithNibName:@"TabViewController" bundle:nil];

    self.window.rootViewController = _loginController; //for test for your case it contains tour view controller  
    [self.window makeKeyAndVisible];
    return YES;
 }

 - (void)showTabController;
 {
    [UIView transitionWithView:self.window duration:0.5 options:UIViewAnimationOptionTransitionFlipFromLeft animations:^{
    self.window.rootViewController = _tabViewController;
    } completion:^(BOOL finished) {
      // [_tabWindow makeKeyAndVisible];
    }];
 }

【讨论】:

  • 您好,感谢您的回复。我试过了,它工作正常,但不能满足要求。顺便说一句,我应该总是在 AppDelegate 中启动标签栏吗?
  • 是的,登录成功后就不需要 loginview 控制器了,app delegate 是用来保存 tabviewcontroller 的,它可以很容易地访问你的 tabview 控制器表单 app delegate
  • 您的代码在正确声明标签栏控制器的情况下工作正常。但是当我的第二个控制器(LoginViewController)辞职时,我想将标签栏控制器显示为背景。你能帮忙吗?
【解决方案2】:

做一件事,

在 AppDelegate.h 中创建 UINavigationController,以便您可以在任何地方访问它。

逻辑

当您需要更改导航控制器时,您必须将控制器放入导航堆栈。

所以首先你必须创建 ViewController/Tabbarcontroller 对象并将其分配给 navigationController 然后显示 navigationController。

AppDelegate* myDelegate = (((AppDelegate*) [UIApplication sharedApplication].delegate));
InitialViewController *initialVC = [self.storyboard instantiateViewControllerWithIdentifier:@“InitialVC"];
myDelegate.navController = [[UINavigationController alloc] initWithRootViewController:initialVC];
myDelegate.window.rootViewController = myDelegate.navController;
[myDelegate.window makeKeyAndVisible];

【讨论】:

  • 这不是问题
  • 只是你必须创建像初始化它的对象。
猜你喜欢
  • 1970-01-01
  • 2012-07-26
  • 1970-01-01
  • 2017-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多