(六)TabBarController的简单自定义

RootTabBarController

这个类用来设置标签栏控制器,继承自系统的UITabBarController。
在此先大致说下一般app的结构。一般来说结构就两种,一种是像美团淘宝之类的,下边是一个标签栏控制器,划分成4个或5个模块。

这里写图片描述

另一种是像百度地图 之类的,看似只有一个主界面
这里写图片描述
开发前先明确自己的结构是属于哪种类型的,不要出现根部是ViewController,然后push到下一个界面是TabbarController。
这里写图片描述
错乱的结构一个是逻辑不清晰,另一个是后期不同业务线界面跨越性的跳转会变得麻烦。即使是有需求需要完成一个控制器后面是多个控制器这样的,我们也不用tabbarController来实现,我们可以用Viewcontroller容器等其他方案来实现。本身tabbarController设计出来便是用来作为根结构分模块的。

在开发前我们需要明确下哪些是我们必须的业务线,哪些是业务之外的额外功能线。举个简单例子。比如说登录,注册这些功能实际上和我们的主功能是关系不大的。我们便可以剔除出来。在storyboard中便可以表示为如下两条开发线,使其完全隔离开来,当我们登录时将根部控制器换为登录的控制器,登录或注册完成后需要进入主界面时则将根部控制器变为TabbarController。后续代码会有相应的演示。
这里写图片描述

先让我们建一个根控制器,进入下界面。
关于底部标签栏上的自定义,我使用的方法比较简单,直接在原有的tabbar上覆盖一层view,然后再在这层view上添加button,当点击button时触发TabbarController的方法。详见代码
1. 建立继承自UITabBarController的根标签控制器RootTabBarController,同时再生成一个同名的storyboard。
2. RootTabBarController的storyboard中拖拽一个TabBarController,类型和Storyboard ID都设置为同名的RootTabBarController,并将其设置为初始化控制器
3. 工程配置环境设置Main Interface为RootTabBarController
4. 删除原有的Main.storybard
启动程序确保成功。

这里写图片描述

这里写图片描述

我这里生成控制器时没有使用xib而是生成的一个同名的storyboard。简单的说我是将storyboard当做xib来用的。Storyboard在拖动组件展示ui,或者复制storyboard时都比xib好用。
另外虽然storyboard中可以放置完整的整个app的控制器界面,但是我仍然是一个Controller对应一个storyboard。一个是因为开发的电脑显示器无法同时展示过多的界面,另一个是因为每次点击storyboard后,即使没有修改,git都认为是有变动,在团队开发时大家点入同一个storyboard中就会造成冲突。
为了能方便的调用storyboard我们可以写一个宏来使用,如下,这是为什么我要将类名和storyboard名以及storyboard中对于控制器的ID设置为一样的原因。

接着我们封装一个用于标签栏上自定义的TabBarBtn,在RootTabbarController放置TabBarbtn到标签栏上,设置TabBarBtn点击时触发的事件来实现标签栏切换的功能。因为是一边写一边改,所以写的时候会忽略很多修改后的地方,可自行查阅项目代码,
这里写图片描述
详情如下:

#import "RootTabBarController.h"
#import "HomeViewController.h"
#import "MessageViewController.h"
#import "FriendViewController.h"
#import "OurViewController.h"
#import "TabBarBtn.h"

@interface RootTabBarController ()
{
    NSUInteger selectIndex;
    UIView *tabbarView;
}

@end

@implementation RootTabBarController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    //初始化控制器
    [self initViews];

    //初始化标签栏
    [self initTabbarView];
}

//初始化控制器
- (void)initViews
{
    HomeViewController *homeCon = gotStoryController(@"HomeViewController");
    BaseNaviController *homeNavi = [[BaseNaviController alloc]initWithRootViewController:homeCon];

    MessageViewController *messageCon = gotStoryController(@"MessageViewController");
    BaseNaviController *messageNavi = [[BaseNaviController alloc]initWithRootViewController:messageCon];

    FriendViewController *friendCon = gotStoryController(@"FriendViewController");
    BaseNaviController *friendNavi = [[BaseNaviController alloc]initWithRootViewController:friendCon];

    OurViewController *ourCon = gotStoryController(@"OurViewController");
    BaseNaviController *ourNavi = [[BaseNaviController alloc]initWithRootViewController:ourCon];

    NSArray *navis = @[homeNavi,messageNavi,friendNavi,ourNavi];
    self.viewControllers = navis;

}


/**
 初始化标签栏

 - returns: void
 */
#pragma mark 初始化标签栏
- (void)initTabbarView
{
    tabbarView = [[UIView alloc]initWithFrame:self.tabBar.bounds];
    tabbarView.backgroundColor = [UIColor whiteColor];
    [self.tabBar addSubview:tabbarView];
    self.tabBar.autoresizesSubviews = NO;
    tabbarView.autoresizesSubviews = NO;


    NSArray *backgroud = @[@"tb_home_n",@"tb_message_n",@"tb_bbs_n",@"tb_me_n"];
    NSArray *heightBackground = @[@"tb_home_s",@"tb_message_s",@"tb_bbs_s",@"tb_me_s"];
    NSArray *titles = @[@"首页",@"消息",@"好友",@"我的"];
    for (int i=0; i<backgroud.count; i++) {
        NSString *backImage = backgroud[i];
        NSString *heightImage = heightBackground[i];
        NSString *title = titles[i];

        TabBarBtn *button = [TabBarBtn buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake(kScreenWidth/titles.count*i, 0, kScreenWidth/titles.count, tabbarView.height);
        button.tag = i+100;
        [button setTitle:title forState:UIControlStateNormal];
        button.titleLabel.font = [UIFont systemFontOfSize:12];
        button.titleLabel.textAlignment = NSTextAlignmentCenter;
        [button setTitleColor:[UIColor darkGrayColor] forState:UIControlStateNormal];
        [button setTitleColor:kColor(46, 199, 255) forState:UIControlStateDisabled];
        [button setImage:[UIImage imageNamed:backImage] forState:UIControlStateNormal];
        [button setImage:[UIImage imageNamed:heightImage] forState:UIControlStateDisabled];
        [button addTarget:self action:@selector(selectedTab:) forControlEvents:UIControlEventTouchUpInside];
        [tabbarView addSubview:button];
        if (i == 0) {
            button.enabled = NO;
        }
    }

}


#pragma mark - -------------------------Actions-------------------
#pragma mark tabBar按钮点击事件
/**
 *  tabBar按钮点击事件
 *
 *  @param button tabBar按钮
 */
- (void)selectedTab:(UIButton *)button {

    self.selectedIndex = button.tag-100;


}
/**
 *  选择不同的tabBar按钮后修改不同的按钮状态
 *
 *  @param selectedIndex tabbarController的值
 */
- (void)setSelectedIndex:(NSUInteger)selectedIndex
{
    [super setSelectedIndex:selectedIndex];

    for (int i = 100; i<105; i++) {
        UIButton *btn =  (UIButton *)[tabbarView viewWithTag:i];
        btn.enabled = YES;
    }
    UIButton *btn =  (UIButton *)[tabbarView viewWithTag:selectedIndex+100];
    btn.enabled = NO;
    //每次点击后都需要将自己的tabbarview放置在最顶层,放置系统的tabbarItem覆盖
    [self.tabBar insertSubview:tabbarView atIndex:self.tabBar.subviews.count-1];

}

//系统自动调用默认方法隐藏掉tabbar上面的字体
+ (void)initialize
{
    // 通过appearance统一设置所有UITabBarItem的文字属性
    // 后面带有UI_APPEARANCE_SELECTOR的方法, 都可以通过appearance对象来统一设置
    NSMutableDictionary *attrs = [NSMutableDictionary dictionary];
    attrs[NSFontAttributeName] = [UIFont systemFontOfSize:0];
    attrs[NSForegroundColorAttributeName] = [UIColor clearColor];

    NSMutableDictionary *selectedAttrs = [NSMutableDictionary dictionary];
    attrs[NSFontAttributeName] = [UIFont systemFontOfSize:0];
    attrs[NSForegroundColorAttributeName] = [UIColor clearColor];

    UITabBarItem *item = [UITabBarItem appearance];
    [item setTitleTextAttributes:attrs forState:UIControlStateNormal];
    [item setTitleTextAttributes:selectedAttrs forState:UIControlStateSelected];
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值