TabBar的使用详解

作者: Jabber_YQ | 来源:发表于2016-09-19 22:18 被阅读7136次

现如今大多数的app都会用到tabbar,然后tabbar的创建却是各种各样的。下面来做个总结。闲话不多说,直接上代码。

一、利用系统自带的tabbar

首先先设置图片,图片必须得经过UIImageRenderingModeAlwaysOriginal处理,否则图片在选中情况下会被系统渲染,改成蓝色。

    // 五套图片
    UIImage *homepageImage = [UIImage imageNamed:@"tab_home"];
    UIImage *homepageImageSelected = [UIImage imageNamed:@"tab_home_sel"];
    homepageImage = [homepageImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    homepageImageSelected = [homepageImageSelected imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    
    UIImage *collectionImage = [UIImage imageNamed:@"tab_collect"];
    UIImage *collectionImageSelected = [UIImage imageNamed:@"tab_collect_sel"];
    collectionImage = [collectionImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    collectionImageSelected = [collectionImageSelected imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    
    UIImage *messageImage = [UIImage imageNamed:@"tab_message"];
    UIImage *messageImageSelected = [UIImage imageNamed:@"tab_message_sel"];
    messageImage = [messageImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    messageImageSelected = [messageImageSelected imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    
    UIImage *personalImage = [UIImage imageNamed:@"tab_me"];
    UIImage *personalImageSelected = [UIImage imageNamed:@"tab_me_sel"];
    personalImage = [personalImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    personalImageSelected = [personalImageSelected imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    
    UIImage *searchImage = [UIImage imageNamed:@"tab_search"];
    UIImage *searchImageSelected = [UIImage imageNamed:@"tab_search_sel"];
    searchImage = [searchImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    searchImageSelected = [searchImageSelected imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];

接下去设置tabbar的自控制器以及属性,最后添加。举例:

    /*首页*/
    SKNavigationController *home = [[SKNavigationController alloc] initWithRootViewController:[[SKHomeViewController alloc] init]];
    [self setupChildControllerWith:home normalImage:homepageImage selectedImage:homepageImageSelected title:@"首页"];

为了方便可以自己写一个方法来完成这个任务。

- (void)setupChildControllerWith:(UIViewController *)childViewController normalImage:(UIImage *)normalImage selectedImage:(UIImage *)selectedImage title:(NSString *)title
{
    childViewController.tabBarItem.title = title;
    childViewController.tabBarItem.image = normalImage;
    childViewController.tabBarItem.selectedImage = selectedImage;
    
    [self addChildViewController:childViewController];
}

效果如图

屏幕快照 2016-09-19 下午9.32.45.png

仔细看会发现一个问题,那就是首页选中的时候,字体的颜色和app的风格颜色不一致,不美观,解决这个问题的方法是添加以下代码

[[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor blackColor], NSForegroundColorAttributeName, nil] forState:UIControlStateNormal];
    
[[UITabBarItem appearance] setTitleTextAttributes:
[NSDictionary dictionaryWithObjectsAndKeys:[UIColor redColor],NSForegroundColorAttributeName, nil]forState:UIControlStateSelected];

效果图:


屏幕快照 2016-09-19 下午9.33.09.png

显然根据代码也可知道同时可以更改字体大小之类的其他属性
然而有些小清新的app不需要下面的label,直接是一个图标,例如这样:

屏幕快照 2016-09-19 下午9.34.05.png

解决方法就是修改下面的方法并不传title属性

- (void)setupChildControllerWith:(UIViewController *)childViewController normalImage:(UIImage *)normalImage selectedImage:(UIImage *)selectedImage title:(NSString *)title
{
    childViewController.tabBarItem.title = title;
    childViewController.title = title;
    childViewController.tabBarItem.image = normalImage;
    childViewController.tabBarItem.selectedImage = selectedImage;
// 加一行,移动image的位置
    childViewController.tabBarItem.imageInsets = UIEdgeInsetsMake(7.0, 0, - 7.0, 0);
    
    [self addChildViewController:childViewController];
}

二、利用数组的enumerateObjectsUsingBlock方法设置tabbar属性

代码如下

NSArray *childItemsArray = @[
                                 @{kClassKey  : @"MXHomeViewController",
                                   kTitleKey  : @"首页",
                                   kImgKey    : @"tab_button_home_nor",
                                   kSelImgKey : @"tab_button_home_sel"},
                                 
                                 @{kClassKey  : @"MXMapViewController",
                                   kTitleKey  : @"地图",
                                   kImgKey    : @"tab_button_map_nor",
                                   kSelImgKey : @"tab_button_map_sel"},
                                 
                                 @{kClassKey  : @"MXTimeLineViewController",
                                   kTitleKey  : @"行圈",
                                   kImgKey    : @"tab_button_discover_nor",
                                   kSelImgKey : @"tab_button_discover_sel"},
                                 
                                 @{kClassKey  : @"MXMineViewController",
                                   kTitleKey  : @"我的",
                                   kImgKey    : @"tab_button_me_nor",
                                   kSelImgKey : @"tab_button_me_sel"} ];
    
    [childItemsArray enumerateObjectsUsingBlock:^(NSDictionary *dict, NSUInteger idx, BOOL *stop) {
        UIViewController *vc = [NSClassFromString(dict[kClassKey]) new];
        vc.title = dict[kTitleKey];
        MXBaseNavigationController *nav = [[MXBaseNavigationController alloc] initWithRootViewController:vc];
        UITabBarItem *item = nav.tabBarItem;
        item.title = dict[kTitleKey];
        item.image = [UIImage imageNamed:dict[kImgKey]];
        item.selectedImage = [[UIImage imageNamed:dict[kSelImgKey]] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
        [item setTitleTextAttributes:@{NSForegroundColorAttributeName : Global_tintColor} forState:UIControlStateSelected];
        [self addChildViewController:nav];
    }];

当然,kClassKey等四个是我自己写的宏。

三、自定义tabbar

首先新建一个tabbar,继承自UITabBar,然后在tabbar上add需要的按钮来充当tabbarButton

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        UIButton *leftViewBtn = [[UIButton alloc] init];
        [leftViewBtn setTitle:@"钥匙" forState:UIControlStateNormal];
        [leftViewBtn setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
        [leftViewBtn setTitleColor:[UIColor orangeColor] forState:UIControlStateHighlighted];
        [leftViewBtn addTarget:self action:@selector(buttonDidClick:) forControlEvents:UIControlEventTouchUpInside];
        leftViewBtn.tag = 0;
        [self addSubview:leftViewBtn];
        self.leftViewBtn = leftViewBtn;
    
        UIButton *openBtn = [[UIButton alloc] init];
        [openBtn setTitle:@"开锁" forState:UIControlStateNormal];
        [openBtn setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
        [openBtn setTitleColor:[UIColor orangeColor] forState:UIControlStateSelected];
        [openBtn addTarget:self action:@selector(buttonDidClick:) forControlEvents:UIControlEventTouchUpInside];
        openBtn.tag = 1;
        [self addSubview:openBtn];
        self.openBtn = openBtn;
    
        UIButton *shareBtn = [[UIButton alloc] init];
        [shareBtn setTitle:@"分享" forState:UIControlStateNormal];
        [shareBtn setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
        [shareBtn setTitleColor:[UIColor orangeColor] forState:UIControlStateSelected];
        [shareBtn addTarget:self action:@selector(buttonDidClick:) forControlEvents:UIControlEventTouchUpInside];
        shareBtn.tag = 2;
        [self addSubview:shareBtn];
        self.shareBtn = shareBtn;
    }
    return self;
}

在layoutSubviews里面重写位置

- (void)layoutSubviews
{
    [super layoutSubviews];
    [self setTabBarButtonFrame];
    [self setleftViewBtnFrame];
}

//设置所有TabbarItem的frame
- (void)setTabBarButtonFrame
{
        //遍历所有的button
        for (UIView *tabbarButton in self.subviews) {
            if (![tabbarButton isKindOfClass:NSClassFromString(@"UITabBarButton")]) continue;
            // 隐藏系统的tabbarButton
            tabbarButton.hidden  = YES;
        }
    
}

//设置leftViewBtn的frame
- (void)setleftViewBtnFrame
{
    self.leftViewBtn.frame = CGRectMake(0, 0, self.width/3, self.height);
    self.openBtn.frame = CGRectMake(self.width/3, 0, self.width/3, self.height);
    self.shareBtn.frame = CGRectMake(self.width/3 + self.width/3, 0, self.width/3, self.height);
}

这样,自定义的tabbar就完成了,回到tabbarController中,更改tabbar

    YQTabBarView *tabbar = [[YQTabBarView alloc] init];
    tabbar.tabBarDelegate = self;
    [self setValue:tabbar forKeyPath:@"tabBar"];

当然,由于是自定义的,所以我们需要写代理方法,这样才能使控制器知道点了哪一个按钮,才能切换相应的控制器。
代理方法以及点击按钮回应如下

@class YQTabBarView;
@protocol YQTabBarViewDelegate <NSObject>
- (void)tabBar:(YQTabBarView *)tabBar didSelectButtonFrom:(NSUInteger)from to:(NSUInteger)to;
@end

- (void)buttonDidClick:(UIButton *)btn
{
    // 如果按到的是钥匙,
        if ([self.tabBarDelegate respondsToSelector:@selector(tabBar:didSelectButtonFrom:to:)]) {
            [self.tabBarDelegate tabBar:self didSelectButtonFrom:self.selecedBtn.tag to:btn.tag];
        }
        self.selecedBtn.selected = NO;
        btn.selected = YES;
        self.selecedBtn = btn;
    }
}

效果如下,可以加上图片然后更改按钮的image和titlelabel的位置

屏幕快照 2016-09-19 下午10.16.56.png

相关文章

网友评论

  • 邦_:现在需要隐藏tabbar+返回手势。 自定义的tabbar没办法像系统那样随着界面一起移动,有没有好的思路?
  • 清無:[self setValue:tabbar forKeyPath:@"tabBar"];
    self.tabbar = tabbar;
    设置2次为何?
    Jabber_YQ:@菲拉兔 呃呃呃 这句话没用 我去掉 这个是很早以前写的代码
  • 马铃薯蜀黍:总结的不错,至少说明作者有一定功底的~~还有一种用一个view自定义tabbar 代理切换
    Jabber_YQ:@马铃薯蜀黍 那个有一个问题 就是系统自带的button会覆盖在自定义的view上,遮不住啊,有没有好的方法
    马铃薯蜀黍:@Jabber_YQ 恩 覆盖在tabbar上
    Jabber_YQ:@马铃薯蜀黍 是tabbar上面addview一个自定义的继承uiview的view嘛

本文标题:TabBar的使用详解

本文链接:https://www.haomeiwen.com/subject/fudnettx.html