一:首先查看一下關於UITabBarController的定義 UITabBarController和UINavigationController一樣是用來管理試圖控制器的,與導航控制器不同,tabBarController控制器使用數組管理子試圖控制器的,並且子試圖之間是平等關係,導航控制器所管理 ...
一:首先查看一下關於UITabBarController的定義
NS_CLASS_AVAILABLE_IOS(2_0) @interface UITabBarController : UIViewController <UITabBarDelegate, NSCoding> //設置控制器數組 @property(nullable, nonatomic,copy) NSArray<__kindof UIViewController *> *viewControllers; //設置控制器數組 動畫 - (void)setViewControllers:(NSArray<__kindof UIViewController *> * __nullable)viewControllers animated:(BOOL)animated; //選中的控制器 @property(nullable, nonatomic, assign) __kindof UIViewController *selectedViewController; //選中索引值 @property(nonatomic) NSUInteger selectedIndex; //當item超過五個時 就會有一個更多 @property(nonatomic, readonly) UINavigationController *moreNavigationController; @property(nullable, nonatomic, copy) NSArray<__kindof UIViewController *> *customizableViewControllers; //tab條 @property(nonatomic,readonly) UITabBar *tabBar NS_AVAILABLE_IOS(3_0); //委托 @property(nullable, nonatomic,weak) id<UITabBarControllerDelegate> delegate; @end
UITabBarController和UINavigationController一樣是用來管理試圖控制器的,與導航控制器不同,tabBarController控制器使用數組管理子試圖控制器的,並且子試圖之間是平等關係,導航控制器所管理的試圖控制器之間是在出桟和入桟的關係;
知識點1:在Application的中編碼,平時項目要使用繼承一個於UITabBarController的控制器裡面
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]]; self.window.backgroundColor = [UIColor whiteColor]; //初始化一個tabBar控制器 UITabBarController *tb = [[UITabBarController alloc]init]; //設置UIWindow的rootViewController為UITabBarController self.window.rootViewController = tb; //創建相應的子控制器 UIViewController *vc1 = [[UIViewController alloc]init]; vc1.view.backgroundColor = [UIColor greenColor]; vc1.tabBarItem.title = @"首頁"; vc1.tabBarItem.image = [[UIImage imageNamed:@"Home_normal"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; vc1.tabBarItem.selectedImage = [[UIImage imageNamed:@"Home_selected"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; UIViewController *vc2 = [[UIViewController alloc]init]; vc2.view.backgroundColor = [UIColor blueColor]; vc2.tabBarItem.title = @"分類"; vc2.tabBarItem.image = [[UIImage imageNamed:@"List_normal"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; vc2.tabBarItem.selectedImage = [[UIImage imageNamed:@"List_selected"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; [[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor colorWithRed:102.0/255 green:102.0/255 blue:102.0/255 alpha:1.0],NSForegroundColorAttributeName, [UIFont systemFontOfSize:10.0],NSFontAttributeName,nil] forState:UIControlStateNormal]; [[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor colorWithRed:255.0/255 green:73.0/255 blue:87.0/255 alpha:1.0],NSForegroundColorAttributeName, [UIFont systemFontOfSize:10.0],NSFontAttributeName,nil] forState:UIControlStateSelected]; //把子控制器添加到UITabBarController //[tb addChildViewController:c1]; //[tb addChildViewController:c2]; //或者 tb.viewControllers = @[vc1,vc2]; [self.window makeKeyAndVisible]; return YES; }
知識點2:moreNavigationController
UITabBar上最多可以顯示5個Tab,當我們往UITabBarController中添加超過的viewController超過5個時候,最後一個一個就會自動變成更多,按照設置的viewControlles的順序,顯示前四個viewController的tabBarItem,後面的tabBarItem將不再顯示。當點擊more時候將會彈出一個標準的navigationViewController,裡面放有其它未顯示的的viewController,並且帶有一個edit按鈕,通過點擊該按鈕可以進入類似與ipod程式中設置tabBar的編輯界面。編輯界面中預設所有的viewController都是可以編輯的,我們可以通過設置UITabBarController的customizableViewControllers屬性來指定viewControllers的一個子集,即只允許一部分viewController是可以放到tabBar中顯示的。但是這塊兒要註意一個問題就是每當UITabBarController的viewControllers屬性發生變化的時候,customizableViewControllers就會自動設置成跟viewControllers一致,即預設的所有的viewController都是可以編輯的,如果我們要始終限制只是某一部分可編輯的話,記得在每次viewControlles發生改變的時候,重新設置一次customizableViewControllers。
二:UITabBarControllerDelegate委托內容
1、視圖將要切換時調用,viewController為將要顯示的控制器,如果返回的值為NO,則無法點擊其它分欄了(viewController指代將要顯示的控制器) - (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController 例如1: - (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController { NSLog(@"被選中的控制器將要顯示的按鈕"); //return NO;不能顯示選中的控制器 return YES; } 2、視圖已經切換後調用,viewController 是已經顯示的控制器 - (void)tabBarController:(UITabBarController *)tabBarControllerdidSelectViewController:(UIViewController *)viewController 例如2: - (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController { NSLog(@"視圖顯示後調用"); } 3、將要開始自定義item的順序 - (void)tabBarController:(UITabBarController *)tabBarController willBeginCustomizingViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers 例如3 - (void)tabBarController:(UITabBarController *)tabBarController willBeginCustomizingViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers { NSLog(@"將要開始自定義item時調用"); NSLog(@"%@",viewControllers); } 4、將要結束自定義item的順序 - (void)tabBarController:(UITabBarController *)tabBarController willEndCustomizingViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers changed:(BOOL)changed 例如4 - (void)tabBarController:(UITabBarController *)tabBarController willEndCustomizingViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers changed:(BOOL)changed { NSLog(@"將要結束自定義item時調用"); NSLog(@"%@",viewControllers); }
5、結束自定義item的順序
- (void)tabBarController:(UITabBarController *)tabBarController didEndCustomizingViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers changed:(BOOL)changed
例如5:
- (void)tabBarController:(UITabBarController *)tabBarController didEndCustomizingViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers changed:(BOOL)changed
{
NSLog(@"已經結束自定義item順序時調用");
NSLog(@"%@",viewControllers);
}
三:UIViewController (UITabBarControllerItem)分類
@interface UIViewController (UITabBarControllerItem) //當前視圖的UITabBarItem對象 @property(null_resettable, nonatomic, strong) UITabBarItem *tabBarItem; //如果視圖控制器是一個標簽欄控制器的子控制器,則返回它。否則返回nil @property(nullable, nonatomic, readonly, strong) UITabBarController *tabBarController; @end
四:關於UITabBar的定義
NS_CLASS_AVAILABLE_IOS(2_0) @interface UITabBar : UIView //委托 @property(nullable,nonatomic,assign) id<UITabBarDelegate> delegate; //UITabBarItem集合 @property(nullable,nonatomic,copy) NSArray<UITabBarItem *> *items; //被選中的item @property(nullable,nonatomic,assign) UITabBarItem *selectedItem; //批量設置items - (void)setItems:(nullable NSArray<UITabBarItem *> *)items animated:(BOOL)animated; - (void)beginCustomizingItems:(NSArray<UITabBarItem *> *)items; - (BOOL)endCustomizingAnimated:(BOOL)animated; - (BOOL)isCustomizing; //渲染色 @property(null_resettable, nonatomic,strong) UIColor *tintColor NS_AVAILABLE_IOS(5_0); //背景色 @property(nullable, nonatomic,strong) UIColor *barTintColor NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR; //被選中的圖片選染色 @property(nullable,nonatomic,strong) UIColor *selectedImageTintColor NS_DEPRECATED_IOS(5_0,8_0,"Use tintColor") UI_APPEARANCE_SELECTOR; //背景圖 @property(nullable, nonatomic,strong) UIImage *backgroundImage NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; //選中指示圖 @property(nullable, nonatomic,strong) UIImage *selectionIndicatorImage NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; //陰影圖 @property(nullable, nonatomic,strong) UIImage *shadowImage NS_AVAILABLE_IOS(6_0) UI_APPEARANCE_SELECTOR; @property(nonatomic) UITabBarItemPositioning itemPositioning NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR; //元素寬度 @property(nonatomic) CGFloat itemWidth NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR; //item間隔 @property(nonatomic) CGFloat itemSpacing NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR; //風格 @property(nonatomic) UIBarStyle barStyle NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR; //是否透明 @property(nonatomic,getter=isTranslucent) BOOL translucent NS_AVAILABLE_IOS(7_0); @end
UITabBar包含多個UITabBarItem,每⼀個UITabBarItem對應⼀個UIViewController。UITabBar的⾼度是49;系統最多只顯⽰5個UITabBarItem,當UITabBarItem超過5個時系統會⾃動增加⼀個更多按鈕,點擊更多按鈕沒有在底部出現的按鈕會以列表的形式顯⽰出來.
五:UITabBarDelegate內容
@protocol UITabBarDelegate<NSObject> @optional - (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item; // called when a new view is selected by the user (but not programatically) - (void)tabBar:(UITabBar *)tabBar willBeginCustomizingItems:(NSArray<UITabBarItem *> *)items; - (void)tabBar:(UITabBar *)tabBar didBeginCustomizingItems:(NSArray<UITabBarItem *> *)items; - (void)tabBar:(UITabBar *)tabBar willEndCustomizingItems:(NSArray<UITabBarItem *> *)items changed:(BOOL)changed; - (void)tabBar:(UITabBar *)tabBar didEndCustomizingItems:(NSArray<UITabBarItem *> *)items changed:(BOOL)changed; @end
對於點擊哪個UITabBarItem響應事件則是在這個委托裡面進行;由於UITabBarController已經遵守了UITabBarDelegate協議,如果有繼承UITabBarController已經可以直接運用UITabBarDelegate裡面的內容;
知識點1:iOS 點擊UITabBar觸發刷新
平常我們在切換UITabBarController底部菜單時,它是不會有刷新的功能;如果要實現刷新的效果可以如下實現;原理如下,在監聽UITabBar點擊的方法中判斷本次點擊的UITabBarItem和上次點擊的是否一樣,如果一樣就發出通知,首先需要自定義一個UITabBarController (比如LLTabBarController);要判斷本次點擊的UITabBarItem和上次點擊的是否一樣,就需要定義一個屬性記錄下來上次點擊的UITabBarItem,併在viewWillAppear:方法中給該屬性賦值預設的UITabBarItem
/** 之前被選中的UITabBarItem */ @property (nonatomic, strong) UITabBarItem *lastItem; - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; // 將預設被選中的tabBarItem保存為屬性 self.lastItem = self.tabBar.selectedItem; } - (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item { // 判斷本次點擊的UITabBarItem是否和上次的一樣 if (item == self.lastItem) { // 一樣就發出通知 [[NSNotificationCenter defaultCenter] postNotificationName:@"LLTabBarDidClickNotification" object:nil userInfo:nil]; } // 將這次點擊的UITabBarItem賦值給屬性 self.lastItem = item; }
在需要實現點擊UITabBar觸發刷新功能的控制器中監聽通知
- (void)viewDidLoad { [super viewDidLoad]; // 監聽UITabBarItem被重覆點擊時的通知 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(tabBarDidClick) name:@"LLTabBarDidClickNotification" object:nil]; } - (void)tabBarDidClick { // 如果本控制器的view顯示在最前面,就下拉刷新 if ([self.view isShowingOnKeyWindow]) { // 判斷一個view是否顯示在根視窗上,該方法在UIView的分類中實現 [self.tableView.header beginRefreshing]; // MJRefresh } }
判斷一個view是否顯示在根視窗上
/** 該方法在UIView的分類中實現 */ - (BOOL)isShowingOnKeyWindow { UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow; // 把這個view在它的父控制項中的frame(即預設的frame)轉換成在window的frame CGRect convertFrame = [self.superview convertRect:self.frame toView: keyWindow]; CGRect windowBounds = keyWindow.bounds; // 判斷這個控制項是否在主視窗上(即該控制項和keyWindow有沒有交叉) BOOL isOnWindow = CGRectIntersectsRect(convertFrame, windowBounds); // 再判斷這個控制項是否真正顯示在視窗範圍內(是否在視窗上,是否為隱藏,是否透明) BOOL isShowingOnWindow = (self.window == keyWindow) && !self.isHidden && (self.alpha > 0.01) && isOnWindow; return isShowingOnWindow; }
在控制器銷毀時要移除通知
- (void)dealloc { // 移除通知 [[NSNotificationCenter defaultCenter] removeObserver:self]; }
六:UITabBarItem的定義
NS_CLASS_AVAILABLE_IOS(2_0) @interface UITabBarItem : UIBarItem - (instancetype)init NS_DESIGNATED_INITIALIZER; //初始化幾中方式 - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER; - (instancetype)initWithTitle:(nullable NSString *)title image:(nullable UIImage *)image tag:(NSInteger)tag; //初始化 標是 圖標 選中圖標 - (instancetype)initWithTitle:(nullable NSString *)title image:(nullable UIImage *)image selectedImage:(nullable UIImage *)selectedImage NS_AVAILABLE_IOS(7_0); - (instancetype)initWithTabBarSystemItem:(UITabBarSystemItem)systemItem tag:(NSInteger)tag; //給當前的分欄控制器的item設置一個選中狀態的圖片 @property(nullable, nonatomic,strong) UIImage *selectedImage NS_AVAILABLE_IOS(7_0); //角標 @property(nullable, nonatomic, copy) NSString *badgeValue; //IOS7以後過期 - (void)setFinishedSelectedImage:(nullable UIImage *)selectedImage withFinishedUnselectedImage:(nullable UIImage *)unselectedImage NS_DEPRECATED_IOS(5_0,7_0,"Use initWithTitle:image:selectedImage: or the image and selectedImage properties along with UIImageRenderingModeAlwaysOriginal"); //IOS7以後過期 - (nullable UIImage *)finishedSelectedImage NS_DEPRECATED_IOS(5_0,7_0); //IOS7以後過期 - (nullable UIImage *)finishedUnselectedImage NS_DEPRECATED_IOS(5_0,7_0); //文字的偏移 @property (nonatomic, readwrite, assign) UIOffset titlePositionAdjustment NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; @end
知識點1:tabBarItem相關屬性運用
1) 用來控制一組控制器的切換,類似選項卡,每個Tab控制一個試圖控制器,點擊哪個tab就顯示對應的試圖控制器,當前的試圖控制器 2) 每個tabBarItem都可以設置title、image/selectedImages、badgeValue 例如: (1).給當前的分欄控制器的item設置一個標題 self.tabBarItem.title = @"我的"; (2).給當前的分欄控制器的item設置一個圖片 self.tabBarItem.image = [UIImage imageNamed:@"tab_buddy_nor@2x"]; (3).給當前的分欄控制器的item設置一個選中狀態的圖片 self.tabBarItem.selectedImage = [UIImage imageNamed:@"tab_me_nor@2x"];//@2x表示給高清屏 30*30的效果好 self.tabBarItem.badgeValue = @"new";//在小圖標的上面家字體加字體 3) 設置選中的顏色 分欄控制器.tabBar.tintColor self.tabBarController.tabBar.tintColor = [UIColor redColor]; 3) TabBar只能顯示五個tab Item,如果超過五個則會自動生成個Morede 標簽顯示剩餘的Tab,這些Tab可以通過編輯顯示在UITabBar上(打開頁面後自動顯示在界面,點擊tabBar右邊) 4) 自定義Item [UITabBarItem alloc]initWithTitle: image: tag: [UITabBarItem alloc]initWithTabBarSystemItem:tag: