1. 程式人生 > >iOS 底部按鈕 工具欄 Tabbar 及 Tabbar 的自定義(中間突出)

iOS 底部按鈕 工具欄 Tabbar 及 Tabbar 的自定義(中間突出)

大多數應用使用系統自帶的Tabbar就能夠滿足需求

通常情況都是在AppDelegate.m裡建立一個UITabBarController將其它的控制器用UINavigationController包裝一層,再新增到UITabBarController的viewControllers裡。再將UITabBarController設定為self.window的rootViewController。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    UITabBarController * tabBarController = [[UITabBarController alloc] init];
    NSArray * array = @[@"OneViewController",@"TwoViewController",@"ThreeViewController",@"FourViewController"];
    NSArray * titleArray = @[@"乾",@"兌",@"離",@"震"];
    NSArray * nomalImageNameArray = @[@"home_32_black",@"wode_32_black",@"home_32_black",@"wode_32_black"];
    NSArray * selectedImageNameArray = @[@"home_32_red",@"wode_32_red",@"home_32_red",@"wode_32_red"];
    NSMutableArray * viewControllers = @[].mutableCopy;
    for (int i = 0; i < array.count; i ++) {
        id viewController = [[NSClassFromString(array[i]) alloc] init];
        [self setItemWithViewController:viewController
                                  title:titleArray[i]
                            normalColor:[UIColor blackColor]
                          selectedColor:[UIColor redColor]
                            normalImage:[UIImage imageNamed:nomalImageNameArray[i]]
                          selectedImage:[UIImage imageNamed:selectedImageNameArray[i]]];
        UINavigationController * navigationController = [[UINavigationController alloc] initWithRootViewController: viewController];
        navigationController.navigationBar.barTintColor = [UIColor whiteColor];
        [viewControllers addObject:navigationController];
    }
    tabBarController.viewControllers = viewControllers;
    tabBarController.tabBar.barTintColor = [UIColor whiteColor];
    self.window.rootViewController = tabBarController;
    [self.window makeKeyAndVisible];
    return YES;
}

- (void)setItemWithViewController:(UIViewController *)viewController title:(NSString *)title normalColor:(UIColor *)normalColor selectedColor:(UIColor *)selectedColor normalImage:(UIImage *)normalImage selectedImage:(UIImage *)selectedImage{
    viewController.tabBarItem.title = title;
    [viewController.tabBarItem setTitleTextAttributes:@{NSForegroundColorAttributeName:normalColor} forState:UIControlStateNormal];
    [viewController.tabBarItem setTitleTextAttributes:@{NSForegroundColorAttributeName:selectedColor} forState:UIControlStateSelected];
    viewController.tabBarItem.image = [normalImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    viewController.tabBarItem.selectedImage = [selectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];//禁止渲染
}

設定tabbar的主要部分提出到了下面的方法裡

設定標題:

viewController.tabBarItem.title = title;

設定未選中時標題顏色: 

 [viewController.tabBarItem setTitleTextAttributes:@{NSForegroundColorAttributeName:normalColor} forState:UIControlStateNormal];

設定設定選中時標題顏色:

 [viewController.tabBarItem setTitleTextAttributes:@{NSForegroundColorAttributeName:selectedColor} forState:UIControlStateSelected];

設定未選中時圖片:

 viewController.tabBarItem.image = [normalImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];

設定選中時的圖片:

viewController.tabBarItem.selectedImage = [selectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];//禁止渲染

其中的禁止圖片渲染一般會用到,否則的話圖片會被渲染成系統預設的顏色,而不是你的圖片顏色。

這裡面選用的圖片需要大小合適,如果過大就會超出範圍而不是隻顯示tabBarItem大小。

自定義的Tabbar就可以更方便的實現更多的功能,如設定背景圖片,控制每個按鈕大小,設定按鈕凸出,給按鈕新增動畫等等。

首先繼承自UIView建立一個FTTabbar類

FTTabbar.h中設定了三個屬性:

@property(nonatomic, strong)NSArray * items;
@property(nonatomic, assign)NSInteger selectedIndex;
@property(nonatomic, copy)void(^onClickChangeSelectedIndex)(NSInteger selectedIndex);

其中items用來傳入標題,圖片,字型大小,顏色等資訊。

selectedIndex用來傳入當前啟動時顯示的介面下標(從0開始)。

onClickChangeSelectedIndex   block 也可以用代理來寫,用作點選按鈕的回撥,通知TabbarController切換介面。

FTTabbar.m中也是三個主要內容,先貼上全部程式碼

#import "FTTabBar.h"
#import "DEButton.h"
@interface FTTabBar()
@property(nonatomic, strong)UIImageView * backImageView;
@property(nonatomic, strong)DEButton * currentButton;
@end
typedef NS_ENUM(NSInteger,TabBarBtnTag) {
    FirstTabBarBtnTag = 100,
};
@implementation FTTabBar

- (id)initWithFrame:(CGRect)frame{
    if (self = [super initWithFrame:frame]) {
        [self setUp];
    }
    return self;
}

- (void)setUp{
    [self addBackImageView];
}

- (void)addBackImageView{
    self.backImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, self.frame.size.height)];
    self.backImageView.userInteractionEnabled = YES;
    self.backImageView.backgroundColor = [UIColor yellowColor];
    [self addSubview:self.backImageView];
}

- (void)setItems:(NSArray *)items{
    _items = items;
    [self setButtons];
}

- (void)setButtons{
    CGFloat width = self.frame.size.width;
    CGFloat btnW = width/_items.count;
    for (int i = 0; i < _items.count; i ++) {
        DEButton * button = [[DEButton alloc] initWithFrame:CGRectMake(btnW * i, 0, btnW, self.frame.size.height)
                                            arrangementType:ArrangementTypeTextDown
                                                  imageSize:CGSizeMake(30, 30)];
        button.backgroundColor = [UIColor colorWithRed:arc4random()%255/255.f green:arc4random()%255/255.f blue:arc4random()%255/255.f alpha:1];
        NSDictionary * dict = _items[i];
        button.titleLabel.textAlignment = NSTextAlignmentCenter;
        button.titleLabel.font = [UIFont systemFontOfSize:12];
        [button setImage:[UIImage imageNamed:dict[@"imageNormal"]] forState:UIControlStateNormal];
        [button setImage:[UIImage imageNamed:dict[@"imageSelected"]] forState:UIControlStateSelected];
        [button setTitleColor:dict[@"colorNormal"] forState:UIControlStateNormal];
        [button setTitleColor:dict[@"colorSelected"] forState:UIControlStateSelected];
        [button setTitle:dict[@"title"] forState:UIControlStateNormal];
        [button addTarget:self action:@selector(onClickButton:) forControlEvents:UIControlEventTouchUpInside];
        button.tag = FirstTabBarBtnTag + i;
        [self.backImageView addSubview:button];
        if (i == self.selectedIndex) {
            button.selected = YES;
            self.currentButton = button;
        }
    }
}

- (void)onClickButton:(DEButton *)sender{
    if (self.onClickChangeSelectedIndex) {
        self.onClickChangeSelectedIndex(sender.tag - FirstTabBarBtnTag);
    }
    
    self.currentButton.selected = NO;
    sender.selected = YES;
    self.currentButton = sender;
}


@end

backImageView用來設定自定義tabbar的背景圖片,也可以不使用

currentButton表示當前選中的按鈕,此處按鈕為自定義按鈕前面有一篇按鈕圖片和文字的排列說的就是這個按鈕

接下來

第一步就是在initWithFrame的方法裡建立背景ImageView圖片和顏色隨意設定

- (void)addBackImageView{
    self.backImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, self.frame.size.height)];
    self.backImageView.userInteractionEnabled = YES;
    self.backImageView.backgroundColor = [UIColor yellowColor];
    [self addSubview:self.backImageView];
}

第二步是在items的setter中根據傳入的資料來建立tabbar的按鈕

- (void)setButtons{
    CGFloat width = self.frame.size.width;
    CGFloat btnW = width/_items.count;
    for (int i = 0; i < _items.count; i ++) {
        DEButton * button = [[DEButton alloc] initWithFrame:CGRectMake(btnW * i, 0, btnW, self.frame.size.height)
                                            arrangementType:ArrangementTypeTextDown
                                                  imageSize:CGSizeMake(30, 30)];
        button.backgroundColor = [UIColor colorWithRed:arc4random()%255/255.f green:arc4random()%255/255.f blue:arc4random()%255/255.f alpha:1];
        NSDictionary * dict = _items[i];
        button.titleLabel.textAlignment = NSTextAlignmentCenter;
        button.titleLabel.font = [UIFont systemFontOfSize:12];
        [button setImage:[UIImage imageNamed:dict[@"imageNormal"]] forState:UIControlStateNormal];
        [button setImage:[UIImage imageNamed:dict[@"imageSelected"]] forState:UIControlStateSelected];
        [button setTitleColor:dict[@"colorNormal"] forState:UIControlStateNormal];
        [button setTitleColor:dict[@"colorSelected"] forState:UIControlStateSelected];
        [button setTitle:dict[@"title"] forState:UIControlStateNormal];
        [button addTarget:self action:@selector(onClickButton:) forControlEvents:UIControlEventTouchUpInside];
        button.tag = FirstTabBarBtnTag + i;
        [self.backImageView addSubview:button];
        if (i == self.selectedIndex) {
            button.selected = YES;
            self.currentButton = button;
        }
    }
}

最後在按鈕的點選方法進行回撥將點選資訊傳遞給TabbarController

- (void)onClickButton:(DEButton *)sender{
    if (self.onClickChangeSelectedIndex) {
        self.onClickChangeSelectedIndex(sender.tag - FirstTabBarBtnTag);
    }
    
    self.currentButton.selected = NO;
    sender.selected = YES;
    self.currentButton = sender;
}

使用方法,在這裡是建立了一個自定義個MyTabbarController繼承自TabbarController

MyTabbarController.m的全部程式碼

#import "MyTabbarController.h"
#import "FTTabBar.h"

@interface MyTabbarController ()
@property(nonatomic, strong)NSMutableArray * items;
@end

@implementation MyTabbarController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self addViewControllers];
    [self addTabbar];
}

- (void)addViewControllers{
    NSMutableArray * arrayM = @[].mutableCopy;
    self.items = @[].mutableCopy;
    NSArray * titleArray = @[@"首頁",@"第二頁",@"第三頁",@"我的"];
    NSArray * imageArray = @[@"home_32_black",@"wode_32_black",@"home_32_black",@"wode_32_black"];
    NSArray * selectedArray = @[@"home_32_red",@"wode_32_red",@"home_32_red",@"wode_32_red"];
    NSArray * viewControllerNameArray = @[@"UIViewController",@"UIViewController",@"UIViewController",@"UIViewController"];
    for (int i = 0; i < viewControllerNameArray.count; i ++) {
        UIViewController * viewController = [[NSClassFromString(viewControllerNameArray[i]) alloc] init];
        UINavigationController * nav = [[UINavigationController alloc] initWithRootViewController:viewController];
        viewController.view.backgroundColor = [UIColor colorWithRed:arc4random()%255/255.f green:arc4random()%255/255.f blue:arc4random()%255/255.f alpha:1];
        [arrayM addObject:nav];
        NSMutableDictionary * dictM = @{}.mutableCopy;
        dictM[@"imageNormal"] = imageArray[i];
        dictM[@"imageSelected"] = selectedArray[i];
        dictM[@"colorNormal"] = [UIColor darkGrayColor];
        dictM[@"colorSelected"] = [UIColor redColor];
        dictM[@"title"] = titleArray[i];
        [self.items addObject:dictM];
    }
    [self setViewControllers:arrayM animated:YES];
}

- (void)addTabbar{
    FTTabBar * tabbar = [[FTTabBar alloc] initWithFrame:CGRectMake(0, 0, self.tabBar.frame.size.width, self.tabBar.frame.size.height)];
    [self.tabBar addSubview:tabbar];
    tabbar.items = self.items;
    __weak MyTabbarController * weakSelf = self;
    tabbar.onClickChangeSelectedIndex = ^(NSInteger selectedIndex) {
        weakSelf.selectedIndex = selectedIndex;
    };
}


@end

還是兩個步驟:

1.新增子控制器到TabBarController也就是addViewControllers方法

2.新增自定義tabbar到系統的tabbar上也就是addTabbar方法