UITabBarController 和 UINavigationController 幾乎是iOS APP的標配。
UITabBarController分欄(標簽欄)控制器, 和UINavigationController導航控制器一樣,都是用來管理視圖控制器的容器類型的控制器。
1、UITabBarController的基本使用
(1)、創建幾個視圖控制器
(2)、將視圖控制器添加到TabBarController
(3)、設置窗口的跟視圖控制器為分欄控制器
(4)、設置分欄控制器的顯示樣式
UIViewController *vc1 = [[UIViewController alloc] init]; vc1.view.backgroundColor = [UIColor redColor]; vc1.title = @"VC1"; // 視圖控制器的分欄按鈕 // 視圖控制器的分欄按鈕,如果沒有被顯示創建,並且被使用了,則會自動根據視圖控制器的title來創建 //vc1.tabBarItem; UIViewController *vc2 = [[UIViewController alloc] init]; vc2.view.backgroundColor = [UIColor yellowColor]; vc2.title = @"VC2"; UIViewController *vc3 = [[UIViewController alloc] init]; vc3.view.backgroundColor = [UIColor blueColor]; vc3.title = @"VC3"; UIViewController *vc4 = [[UIViewController alloc] init]; vc4.view.backgroundColor = [UIColor greenColor]; vc4.title = @"VC4"; // 創建分欄(標簽欄)控制器, 和導航控制器一樣,都是用來管理視圖控制器的容器類型的控制器。 // 分欄控制器和導航控制器一樣,也是通過viewControllers來管理其子視圖控制器 UITabBarController *tabBarCtrl = [[UITabBarController alloc] init]; tabBarCtrl.view.backgroundColor = [UIColor cyanColor]; // 把數據中得視圖器交給分欄控制器管理 // 分欄控制器會自動將其管理的視圖控制器的分欄按鈕(UITabBarItem)放到分欄上顯示 tabBarCtrl.viewControllers = @[vc1, vc2, vc3, vc4]; // 設置窗口的跟視圖控制器為分欄控制器 self.window.rootViewController = tabBarCtrl; // 取到分欄控制器的分欄 UITabBar *tabBar = tabBarCtrl.tabBar; // 設置分欄的風格 tabBar.barStyle = UIBarStyleBlack; // 是否透明 tabBar.translucent = NO; // 設置分欄的前景顏色 tabBar.barTintColor = [UIColor brownColor]; // 設置分欄元素項的顏色 tabBar.tintColor = [UIColor purpleColor]; // 設置分欄按鈕的選中指定圖片 tabBar.selectionIndicatorImage = [UIImage imageNamed:@"home.png"]; [self.window makeKeyAndVisible];
效果如圖:
2、UITabBarController和的UINavigationController結合使用
如果有如圖需求:點擊切換到下一個頁面,隱藏UITabBarController。
(1)、創建分欄控制器:
// 創建分欄控制器管理的子視圖控制器 - (void)createViewControllers { OneViewController *oneVC = [[OneViewController alloc] init]; MyNavgationController *navCtrl1 = [[MyNavgationController alloc] initWithRootViewController:oneVC]; // navCtrl1.tabBarItem = [[UITabBarItem alloc] initWithTabBarSystemItem:UITabBarSystemItemSearch tag:0]; TwoViewController *twoVC = [[TwoViewController alloc] init]; UINavigationController *navCtrl2 = [[UINavigationController alloc] initWithRootViewController:twoVC]; ThreeViewController *threeVC = [[ThreeViewController alloc] init]; FourViewController *fourVC = [[FourViewController alloc] init]; FiveViewController *fiveVC = [[FiveViewController alloc] init]; SixViewController *sixVC = [[SixViewController alloc] init]; // 分欄控制器管理的視圖控制器的tabBarController屬性,自動指向分欄控制器。 // 當分欄控制器管理的視圖控制器的個數超過五個時,會自動創建一個more的導航控制器,並且自動將第五個以及以后的視圖控制器添加到more導航控制器中。 self.viewControllers = @[navCtrl1, navCtrl2, threeVC, fourVC, fiveVC, sixVC]; }
(2)、在MyNavgationController里面,重寫跳轉方法:
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated { //1. 取出分欄 UITabBar *tabBar = self.tabBarController.tabBar; // 將frame左移分欄的寬度 CGRect frame = tabBar.frame; frame.origin.x -= tabBar.frame.size.width; // 動畫影藏tabBar [UIView animateWithDuration:0.28 animations:^{ tabBar.frame = frame; }]; [super pushViewController:viewController animated:animated]; } - (UIViewController *)popViewControllerAnimated:(BOOL)animated { //1. 取出分欄 UITabBar *tabBar = self.tabBarController.tabBar; // 將frame左移分欄的寬度 CGRect frame = tabBar.frame; frame.origin.x += tabBar.frame.size.width; // 動畫影藏tabBar [UIView animateWithDuration:0.28 animations:^{ tabBar.frame = frame; }]; return [super popViewControllerAnimated:YES]; }
3、定制UITabBarController
#import "MyTabBar.h" @interface MyTabBarController () <MyTabBarDelegate> // 保存之前選中的按鈕 @property (nonatomic, retain) UIButton *preSelBtn; @end @implementation MyTabBarController - (void)viewDidLoad { [super viewDidLoad]; [self createViewControllers]; [self createTabBar]; } // 創建分欄控制器管理的視圖控制器數據 - (void)createViewControllers { FirstViewController *firstVC = [[FirstViewController alloc] init]; UINavigationController *nav1 =[[UINavigationController alloc] initWithRootViewController:firstVC]; SecondViewController *secondVC = [[SecondViewController alloc] init]; ThirdViewController *thirdVC = [[ThirdViewController alloc] init]; FourthViewController *fourthVC = [[FourthViewController alloc] init]; self.viewControllers = @[nav1, secondVC, thirdVC, fourthVC]; } // 定制tabBar tabBar 49 - (void)createTabBar { // 0. 隱藏分欄控制器自帶的tabbar [self.tabBar setHidden:YES]; MyTabBar *tabBr = [[MyTabBar alloc] init]; tabBr.frame = self.tabBar.frame; tabBr.delegate = self; [self.view addSubview:tabBr]; } #pragma mark - MyTabBarDelegate協議方法 - (void)tabBar:(MyTabBar *)tabBar didSelectItemWithIndex:(NSUInteger)toIndex { // 設置分欄控制器選中的視圖控制器 self.selectedIndex = toIndex; }
@class MyTabBar; @protocol MyTabBarDelegate <NSObject> @optional - (void)tabBar:(MyTabBar *)tabBar didSelectItemWithIndex:(NSUInteger)toIndex; - (void)tabBar:(MyTabBar *)tabBar didSelectItemWithIndex:(NSUInteger)toIndex fromIndex:(NSUInteger)fromIndex; @end @interface MyTabBar : UIImageView @property (nonatomic, assign) id <MyTabBarDelegate> delegate; @end
#import "MyTabBar.h" #define TABBAR_BTN_START_TAG 100 #define BTN_COUNT 4 @interface TabBarButton : UIButton @end @implementation TabBarButton // 重寫高亮的方法。在這個方法中,我們忽略按鈕的高亮狀態 - (void)setHighlighted:(BOOL)highlighted { // NSLog(@"highlighted = %d", highlighted); // [super setHighlighted:NO]; } @end @interface MyTabBar () // 保存分欄之前選中的按鈕 @property (nonatomic, retain) TabBarButton *preSelBtn; @end @implementation MyTabBar - (instancetype)init { if (self = [super init]) { NSLog(@"init"); } return self; } // init方法會調用initWithFrame ,給控件添加子控件在initWithFrame中添加 - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { // 1.2 設置背景視圖的背景圖片 self.image = [UIImage imageNamed:@"tabbg.png"]; // 1.3 設置用戶交互屬性可用(父控件不能與用戶進行交互,則所有子控件都不能與用戶交互) self.userInteractionEnabled = YES; // 2. 在分欄背景上添加按鈕 for (int i = 0; i < BTN_COUNT; i++) { TabBarButton *btn = [TabBarButton buttonWithType:UIButtonTypeCustom]; // 設置正常狀態下的顯示圖片 NSString *imageName = [NSString stringWithFormat:@"tab_%d", i]; [btn setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal]; // 設置按鈕在選中狀態下的顯示圖片 NSString *imageSelName = [NSString stringWithFormat:@"tab_c%d",i]; [btn setImage:[UIImage imageNamed:imageSelName] forState:UIControlStateSelected]; // 第一個按鈕默認為選中 if (i == 0) { btn.selected = YES; self.preSelBtn = btn; } // 監聽按鈕的點擊事件 [btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchDown]; btn.tag = TABBAR_BTN_START_TAG + i; // 將按鈕添加到背景視圖上顯示 [self addSubview:btn]; } } return self; } - (void)btnClick:(TabBarButton *)btn { // 1. 取消之前選中按鈕的選中狀態 self.preSelBtn.selected = NO; // 2. 將當前點擊的按鈕設為選中狀態 btn.selected = YES; // 3. 保存當前選中的按鈕 self.preSelBtn = btn; // 如果代理實現了協議方法,通過協議方法通知代碼當前控件上的第幾個按鈕被點擊了。 if ([self.delegate respondsToSelector:@selector(tabBar:didSelectItemWithIndex:)]) { [self.delegate tabBar:self didSelectItemWithIndex:btn.tag - TABBAR_BTN_START_TAG]; } } // 這個方法在控件的frame(大小)修改后被調用 - (void)layoutSubviews { // 這行代碼不能少 [super layoutSubviews]; // 取出子控件的個數 NSUInteger count = self.subviews.count; // 調整子控件的大小 CGFloat btnY = 0; CGFloat btnW = self.bounds.size.width / count; CGFloat btnH = self.bounds.size.height; int i = 0; // 取出所有的子控件,調整frame for (TabBarButton *btn in self.subviews) { // 設置frame CGFloat btnX = btnW * i; btn.frame = CGRectMake(btnX, btnY, btnW, btnH); i++; } }
效果如圖: