(六)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.
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章