淘先锋技术网

首页 1 2 3 4 5 6 7

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

混用UITabBar与UINavigation做app,tab和nav,有时候显示有时候需要隐藏,记录目前使用的解决方案。


一、效果

1、主页使用UITabBar管理,有三个tab分页

2、在tab分页的根视图时显示tab,隐藏nav。

3、二级页面全部用UINavigationController管理。

4、使用pushViewController打开页面时,隐藏tab,显示nav;

5、导航栏的文字显示黑色

6、导航栏的返回按钮不显示中文

 

二、实现

1.AppDelegate.m

代码如下:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    self.window.rootViewController = [[MainTabBarController alloc] init];
    
    // 设置导航栏的文字为黑色
    // 满足5【导航栏的文字显示黑色】
    [[UINavigationBar appearance] setTintColor: [UIColor blackColor]];

    return YES;
}

// 其他代码.....

在AppDelegate.m中,设置rootViewController为【MainTabBarController】

2.MainTabBarController.m

代码如下:

- (void)viewDidLoad {
    [super viewDidLoad];
    [self createBottomMenuIconButton];
    // 其他代码....
}

-(void)createBottomMenuIconButton{
    NSMutableArray *bottomViewCtrls  = [NSMutableArray arrayWithCapacity:0];

    NSArray* bottomMenus = [self getLocalBottomMenu];
    for (NSDictionary *bottomMenu in bottomMenus) {
        NSString *name =  [bottomMenu objectForKey: @"name"];
        NSString *normal =  [bottomMenu objectForKey: @"normal"];
        NSString *highlighted =  [bottomMenu objectForKey: @"highlighted"];

        //结合 xx.class 对象,动态创建UIViewController
        UIViewController *vc = [[[bottomMenu objectForKey: @"vcclass"] alloc] init];
        // 满足3【二级页面全部用UINavigationController管理】
        UINavigationController *nav = [self createBottomMenu:vc menuName:name normal: normal highlighted: highlighted];
        [self.bottomViewCtrls addObject:nav];
    }
    
    //有底部导航菜单
    // 满足1【使用UITabBar管理,有三个tab分页】
    if(bottomViewCtrls.count > 0){
        self.viewControllers= bottomViewCtrls;
    }
}

- (UINavigationController*) createBottomMenu: (UIViewController*) vc
                                    menuName: (NSString*) menuName
                                      normal: (NSString*) normal
                                 highlighted: (NSString*) highlighted{
    vc.tabBarItem.title = menuName;

    UIImage* imageNormal = [UIImage imageNamed: normal];
    vc.tabBarItem.image = imageNormal;
    UIImage* imagePressed = [UIImage imageNamed: highlighted];
    vc.tabBarItem.selectedImage = [imagePressed imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];

    //将分页设置成UINavigationController的根视图。
    //这样包装之后,才能正常使用pushViewController打开页面
    UINavigationController* nav = [[UINavigationController alloc]initWithRootViewController:vc];
    return nav;
}

-(NSArray *)getLocalBottomMenu{
    NSArray *bottomMenus = @[
        @{@"id":@"home",@"name":@"首页",@"normal":@"tab_home",@"highlighted":@"tab_home_active",@"vcclass":TabItemHome.class},
        @{@"id":@"message",@"name":@"消息",@"normal":@"tab_message",@"highlighted":@"tab_message_active",@"vcclass":TabItemMessage.class},
        @{@"id":@"profile",@"name":@"我的",@"normal":@"tab_profile",@"highlighted":@"tab_profile_active",@"vcclass":TabItemProfile.class}
    ];
    return bottomMenus;
}

(1)通过【self.viewControllers= bottomViewCtrls】设置tab的分页。

(2)如果创建tab分页的时候,不用UINavigationController包装一下,在页面中使用pushViewController,就会报错,提示当前视图不支持UINavigationController。

(3)结合xx.class和[[[bottomMenu objectForKey: @"vcclass"] alloc] init],动态创建UIViewController。

(4)tab分页需要增删改时,修改【getLocalBottomMenu】的代码,即可。

2.tab分页的基类BaseTabViewController

代码如下:

//BaseTabViewController.h
-(void) setTitle:(nonnull NSString*) title;
-(void)openPage:(UIViewController*)page;



//BaseTabViewController.m
- (void)viewDidLoad {
    [super viewDidLoad];
    // 满足6【导航栏的返回按钮不显示中文】
    [self setNavSetting];
    // 其他代码...
}

// 满足2【在tab分页的根视图时显示tab,隐藏nav】
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    // 隐藏导航
    [self.navigationController setNavigationBarHidden:YES animated:animated];
    // 其他代码...
}

// 满足4【使用pushViewController打开页面时,隐藏tab,显示nav】
- (void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    // 显示导航
    [self.navigationController setNavigationBarHidden:NO animated:animated];
    // 其他代码...
}

-(void) setTitle:(nonnull NSString*) title{
    self.navigationItem.title = title;
}
-(void)setNavSetting {
    // 设置导航栏的返回按钮没有中文,对下一个打开的页面起效
    UIBarButtonItem* backBtn = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
    self.navigationItem.backBarButtonItem = backBtn;
    
}

-(void)openPage:(UIViewController*)page {
    // 隐藏下面的tab
    page.hidesBottomBarWhenPushed = YES;

    //通过nav打开页面
    [self.navigationController pushViewController:page animated:YES];
    
}

(1)通过【page.hidesBottomBarWhenPushed = YES】隐藏tabbar;

(2)导航栏的返回按钮,总是要父页设置的。所以,在当前页,需要设置返回按钮,去掉它自带的文字;

(3)【viewWillAppear】当页面要展示的时候,隐藏导航;【viewWillDisappear】当页面要隐藏时,显示导航。

3.HomeTab.m

代码如下:

//HomeTab.h
@interface HomeTab : BaseTabViewController
// 其他代码.....


//HomeTab.m

// 在要打开页面的方法中,调用openPage打开PageA页面
[self openPage: [[PageA alloc] init]];

在h文件中,将HomeTab类设置成继承BaseTabViewController,所以在要打开页面的方法中,可以直接调用openPage打开PageA页面。

以上,就是tab相关的设置

4.二级页面的基类BasePageViewController

代码如下:

- (void)viewDidLoad {
    [super viewDidLoad];
    // 满足6【导航栏的返回按钮不显示中文】
    [self setNavSetting];
    // 其他代码...
}

-(void)setNavSetting {
    // 设置导航栏的返回按钮没有中文,对下一个打开的页面起效
    UIBarButtonItem* backBtn = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
    self.navigationItem.backBarButtonItem = backBtn;
    
}

-(void) setTitle:(nonnull NSString*) title {
    self.navigationItem.title = title;
}

将复用的内容,做到基类中。

5.二级页面pageA

代码如下:

//PageA.h
@interface PageA : BasePageViewController


//PageA.m

//调用pushViewController打开页面
[self.navigationController pushViewController:page animated:YES];

在h文件中,将PageA类设置成继承BasePageViewController。


总结

以上是我目前使用的一种UITabBar与UINavigation混用方案,基本满足了我的需求。