首页 > 代码库 > 导航栏控制器和标签栏控制器(UINavigationController和UITabBarController)混用

导航栏控制器和标签栏控制器(UINavigationController和UITabBarController)混用

很多时候,在UI设计方面同时需要使用导航控制器和标签栏控制器,这时,需要掌握如何设计结合使用这两种不同控制器。比如手机QQ,程序有三个标签栏(分别为消息、联系人、动态),同时在选择某个联系人或者会话时,会进入聊天的子页面,因此这里同时使用到了标签栏控制器和导航控制器。

我目前所知道有以下方法可实现上述的结合使用效果。

  • 根视图是标签栏控制器,然后每页标签栏又有一个根视图控制器为导航栏控制器的标签,如下代码所示
    // 消息
    MessageViewController* msg = [[MessageViewController alloc] init];
    UINavigationController* navControloler = [[UINavigationController alloc] init];
    [navControloler pushViewController:msg animated:YES];
    [viewArray addObject:navControloler];
    
    // 联系人
    ContactViewController* contact = [[ContactViewController alloc] init];
    navControloler = [[UINavigationController alloc] init];
    [navControloler pushViewController:contact animated:YES];
    [viewArray addObject:navControloler];
    
    // 动态
    FavoriteViewController* favorite = [[FavoriteViewController alloc] init];
    navControloler = [[UINavigationController alloc] init];
    [navControloler pushViewController:favorite animated:YES];
    [viewArray addObject:navControloler];
    
    // 标签栏控制器
    UITabBarController* tabBarController = [[UITabBarController alloc] init];
    tabBarController.viewControllers = viewArray;
    
    // 修改根视图
    AppDelegate* appDelagete = [UIApplication sharedApplication].delegate;
    appDelagete.window.rootViewController = tabBarController;
    上述代码是在ViewController.m文件中,也就是说,APP的根视图控制器可以在AppDelegete外的其他地方修改,因此,可以设计出先显示登录界面,然后再显示程序的主页面,即标签栏页面视图。注意根视图是标签栏,所以返回按钮无效,如下所示
    技术分享
  • 如果上述代码的根视图是导航栏,那么返回按钮是有效的,可以用作退出登录等类似的功能,其主要实现如下,在AppDelegate里设置根视图控制器
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        // Override point for customization after application launch.
        self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
        
        UINavigationController* navController = [[UINavigationController alloc] init];
        [navController pushViewController:[[ViewController alloc] init] animated:YES];
        
        self.window.rootViewController = navController;
        return YES;
    }
    然后ViewController中将标签栏控制器当做导航栏控制器的子视图Push进去,代码为
    - (void) loginSuccess
    {
        // 进入主界面,改变根视图
        NSMutableArray* viewArray = [[NSMutableArray alloc] init];
        
        // 导航控制器+表标签栏控制器相结合使用,
        // 每个标签有一个根导航控制器
        
        // 消息
        MessageViewController* msg = [[MessageViewController alloc] init];
        UINavigationController* navControloler = [[UINavigationController alloc] init];
        [navControloler pushViewController:msg animated:YES];
        [viewArray addObject:navControloler];
        
        // 联系人
        ContactViewController* contact = [[ContactViewController alloc] init];
        navControloler = [[UINavigationController alloc] init];
        [navControloler pushViewController:contact animated:YES];
        [viewArray addObject:navControloler];
        
        // 动态
        FavoriteViewController* favorite = [[FavoriteViewController alloc] init];
        navControloler = [[UINavigationController alloc] init];
        [navControloler pushViewController:favorite animated:YES];
        [viewArray addObject:navControloler];
        
        // 标签栏控制器
        UITabBarController* tabBarController = [[UITabBarController alloc] init];
        tabBarController.viewControllers = viewArray;
       
    #ifdef TABRoot
        // 修改根视图为标签栏控制器
        AppDelegate* appDelagete = [UIApplication sharedApplication].delegate;
        appDelagete.window.rootViewController = tabBarController;
    #else
        // 把标签栏视图控制器push到导航栏控制器内
        [self.navigationController pushViewController:tabBarController animated:YES];
    #endif
    }
    其效果如下所示
    技术分享

导航栏控制器和标签栏控制器(UINavigationController和UITabBarController)混用