一、 UITabBarController的原理
1.1 基本概念
父控制器
:通過標(biāo)簽控制器管理多個(gè)子控制器膨桥,標(biāo)簽控制器就稱為父控制器
子控制器
:添加到標(biāo)簽控制器里的控制器都做為標(biāo)簽控制器的子控制器
標(biāo)簽欄
:也叫選項(xiàng)卡欄容握,方便用戶切換到對應(yīng)的界面弹谁,當(dāng)往標(biāo)簽控制器里添加子控制器弹澎,標(biāo)簽欄就會(huì)有序的自動(dòng)生成對應(yīng)的標(biāo)簽
標(biāo)簽欄按鈕
:也叫標(biāo)簽设联,UITabBarButton捌年,這個(gè)類只有apple內(nèi)部開發(fā)人員才能使用
1.2 UITabBarController原理
當(dāng)UITabBarController做為Window的根控制器時(shí)崖瞭,程序一啟動(dòng),
UITabBarController就會(huì)一次性初始化所有子控制器胚吁,但是默認(rèn)只加載第一個(gè)控制器視圖牙躺,其他視圖控制器只初始化愁憔,但默認(rèn)不會(huì)加載腕扶,只有在需要顯示的時(shí)候才調(diào)用loadView方法加載。
特殊情況:在AppDelegate中設(shè)置其他的子控制器視圖的背景顏色吨掌,就會(huì)提前加載該控制器視圖半抱,但不顯示該視圖。
每一個(gè)控制器視圖
只加載一次膜宋,就會(huì)一直存在內(nèi)存中
窿侈,當(dāng)切換子控制器時(shí)直接顯示,不顯示在屏幕上的子控制器不會(huì)被銷毀秋茫。當(dāng)遇到內(nèi)存警告時(shí)史简,會(huì)釋放掉沒有加載的子控制器。每個(gè)視圖控制器都有一個(gè)tabBarController屬性
肛著,通過它可以訪問所在的UITabBarController圆兵,而且對于UITabBarController的直接子視圖,其tabBarController屬性相當(dāng)于它的父視圖parentViewController枢贿。每個(gè)視圖控制器都有一個(gè)
tabBarItem
屬性殉农,通過它控制視圖在UITabBarController的tabBar中的顯示信息tabBarItem的image屬性必須是
png格式(建議大小32*32)
,并且打開alpha通道否則無法正常顯示局荚。
當(dāng)往UITabBarController添加子控制器超凳,標(biāo)簽欄就會(huì)有序的自動(dòng)生成對應(yīng)的UITabBarButton對象愈污,有多少個(gè)子控制器,標(biāo)簽欄就有多少個(gè)UITabBarButton對象轮傍, 但是子控制器的數(shù)量超過5個(gè)的時(shí)候暂雹,標(biāo)簽欄上的第五個(gè)UITabBarButton對象就會(huì)顯示成”More”類型的按鈕
。
二金麸、UITabBarController的知識點(diǎn)
2.1 關(guān)于UITabBarController
UITabBarController沒有根控制器的概念擎析。
在添加了相同的子控制器,不會(huì)增加tabitem的數(shù)量
挥下。子控器可以是UIViewController揍魂、UINavigationController、UITableViewController或者其他的視圖控制器UITabBarButton在UITabBar中的位置是均分的棚瘟,UITabBar的高度為49现斋,UITabBarButton?面顯?什么內(nèi)容,由對應(yīng)子控制器的tabBarItem屬性來決定
UITabBarController一般作為應(yīng)用程序的rootViewController偎蘸,但是
它不能作為UINavigationController的根控制器
UITabBarController
默認(rèn)只支持豎屏
庄蹋,當(dāng)設(shè)備方向放生變化時(shí)候,它會(huì)查詢viewControllers屬性中包含的所有ViewController迷雪,僅當(dāng)所有的viewController都支持該方向時(shí)
限书,UITabBarController才會(huì)發(fā)生旋轉(zhuǎn),否則默認(rèn)的豎向
2.2 關(guān)于UITabBar
2.2.1 簡介
UITabBar繼承于UIView章咧,方便用戶切換到對應(yīng)的界面倦西,當(dāng)往標(biāo)簽控制器里添加子控制器,標(biāo)簽欄就會(huì)有序的自動(dòng)生成對應(yīng)的標(biāo)簽赁严;創(chuàng)建一個(gè)標(biāo)簽控制器扰柠,就默認(rèn)創(chuàng)建一個(gè)標(biāo)簽欄,標(biāo)簽欄最多顯示5個(gè)標(biāo)簽
2.2.2 UITabBar常用的屬性和方法
// 代理
@property(nonatomic,assign) id<UITabBarDelegate> delegate;
// 設(shè)置數(shù)據(jù)模型疼约,不能給系統(tǒng)默認(rèn)創(chuàng)建的UITabBar設(shè)置items
@property(nonatomic,copy) NSArray *items;
// 設(shè)置選中數(shù)據(jù)模型卤档,不能給系統(tǒng)默認(rèn)創(chuàng)建的UITabBar設(shè)置selectedItem
@property(nonatomic,assign) UITabBarItem *selectedItem;
// iOS7之前,tintColor可以修改背景色
@property(nonatomic,retain) UIColor *tintColor;
// iOS7之后程剥,修改背景色只能用barTintColor
@property(nonatomic,retain) UIColor *barTintColor;
// 設(shè)置UITabBar的背景圖片
@property(nonatomic,retain) UIImage *backgroundImage
// 設(shè)置選中的按鈕的背景圖片
@property(nonatomic,retain) UIImage *selectionIndicatorImage
// 設(shè)置陰影圖片劝枣,但必須設(shè)置backgroundImage屬性
@property(nonatomic,retain) UIImage *shadowImage
// 設(shè)置數(shù)據(jù)模型,不能給系統(tǒng)默認(rèn)創(chuàng)建的UITabBar設(shè)置items
- (void)setItems:(NSArray *)items animated:(BOOL)animated;
代理方法:
// 選中時(shí)調(diào)用
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item;
// 即將編輯時(shí)調(diào)用
- (void)tabBar:(UITabBar *)tabBar willBeginCustomizingItems:(NSArray *)items;
// 編輯時(shí)調(diào)用
- (void)tabBar:(UITabBar *)tabBar didBeginCustomizingItems:(NSArray *)items;
// 即將結(jié)束編輯時(shí)調(diào)用
- (void)tabBar:(UITabBar *)tabBar willEndCustomizingItems:(NSArray *)items changed:(BOOL)changed;
// 結(jié)束編輯時(shí)調(diào)用
- (void)tabBar:(UITabBar *)tabBar didEndCustomizingItems:(NSArray *)items changed:(BOOL)changed;
2.2.3 UITabBarItem
---------- UITabBarItem的常用接口
@interface UITabBarItem : UIBarItem
// 設(shè)置選中圖片
@property(nonatomic,retain) UIImage *selectedImage;
// 設(shè)置角標(biāo)织鲸,一般用于提示用戶有新消息
@property(nonatomic,copy) NSString *badgeValue;
// 初始化UITabBarItem對象
- (instancetype)initWithTitle:(NSString *)title image:(UIImage *)image tag:(NSInteger)tag;
// 初始化UITabBarItem對象
- (instancetype)initWithTitle:(NSString *)title image:(UIImage *)image selectedImage:(UIImage *)selectedImage;
// 初始化UITabBarItem對象
- (instancetype)initWithTabBarSystemItem:(UITabBarSystemItem)systemItem tag:(NSInteger)tag;
@end
---------- UIBarItem的常用接口
@interface UIBarItem : NSObject
// 是否有效
@property(nonatomic,getter=isEnabled) BOOL enabled;
// 設(shè)置標(biāo)題
@property(nonatomic,copy) NSString *title;
// 設(shè)置圖片
@property(nonatomic,retain) UIImage *image;
// 設(shè)置橫向圖片
@property(nonatomic,retain) UIImage *landscapeImagePhone;
// 設(shè)置圖片邊距
@property(nonatomic) UIEdgeInsets imageInsets;
// 設(shè)置橫向圖片邊距
@property(nonatomic) UIEdgeInsets landscapeImagePhoneInsets;
// 設(shè)置對應(yīng)的控制器的標(biāo)簽
@property(nonatomic) NSInteger tag;
@end
---------- UITabBarSystemItem的枚舉類型
typedef NS_ENUM(NSInteger, UITabBarSystemItem) {
UITabBarSystemItemMore,
UITabBarSystemItemFavorites,
UITabBarSystemItemFeatured,
UITabBarSystemItemTopRated,
UITabBarSystemItemRecents,
UITabBarSystemItemContacts,
UITabBarSystemItemHistory,
UITabBarSystemItemBookmarks,
UITabBarSystemItemSearch,
UITabBarSystemItemDownloads,
UITabBarSystemItemMostRecent,
UITabBarSystemItemMostViewed,
};
2.2.4 覆蓋UITabBarController自帶的tabBar為自定義的tabBar操作原理
tabBar上的按鈕是在viewDidAppear的時(shí)候拿到 self.tabBar 再調(diào)用addSubViews添加上去的舔腾,在viewDidAppear之前把控制器的tabBar換成我們自己的tabBar,就會(huì)把tabBar上的按鈕添加到自己的tabBar上昙沦。但是tabBar控制器的tabBar屬性是只讀的琢唾,不能直接賦值,可以利用運(yùn)行時(shí)機(jī)制發(fā)送消息
三盾饮、應(yīng)用
-(void)RTSetUpSubVcs{
TGHomeViewController *HomeVC = [[TGHomeViewController alloc]init];
HomeVC.view.backgroundColor = [UIColor whiteColor];
BSENavigationController *HomeNav = [self ChildVC:HomeVC
WithTitle:@"今托管"
image:@"tabbar_search"
selectedImage:@"tabbar_search_sel"];
TGRootChildrenViewController *childrenVC = [TGRootChildrenViewController new];
BSENavigationController *childrenNav = [self ChildVC:childrenVC
WithTitle:@"小孩"
image:@"tabBar_children"
selectedImage:@"tabBar_children_sel"];
TGMineViewController *MyVC = [TGMineViewController new];
BSENavigationController *MyNav = [self ChildVC:MyVC
WithTitle:@"我的"
image:@"tabBar_mine"
selectedImage:@"tabBar_mine_sel"];
self.tabBar.barTintColor = [UIColor whiteColor];//tabbar 背景色
self.tabBar.translucent = NO;//tarbar非透明
self.viewControllers = @[HomeNav,childrenNav,MyNav];
}
#pragma mark - 根TabBarController 添加子視圖
-(BSENavigationController *)ChildVC:(UIViewController *)VC WithTitle:(NSString *)title image:(NSString *)imagename selectedImage:(NSString *)selectedImageName
{
VC.title = title;
UITabBarItem *barItem = [[UITabBarItem alloc]init];
barItem.title = title;
barItem.image = [[UIImage imageNamed:imagename]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
barItem.selectedImage = [[UIImage imageNamed:selectedImageName]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
[barItem setTitleTextAttributes:@{NSForegroundColorAttributeName: HEXCOLOR(0x666666)} forState:UIControlStateNormal];
// 選中狀態(tài)下的文字顏色
[barItem setTitleTextAttributes:@{NSForegroundColorAttributeName: HEXCOLOR(kBlueGrayColor)} forState:UIControlStateSelected];
BSENavigationController *Nav = [[BSENavigationController alloc]initWithRootViewController:VC];
Nav.tabBarItem = barItem;
return Nav;
}
四采桃、遇到的問題
1.之前初始化寫錯(cuò)了添加子控制器的方法懒熙,設(shè)置了子控制的backgroundColor 導(dǎo)致 tabbarcontroller初始化所有子控制進(jìn)入了didload方法。這樣的直接壞處就是多數(shù)子控制器在didload里面都有網(wǎng)絡(luò)請求方法普办,并且接口都有登錄權(quán)限設(shè)置工扎,如果初始化都直接加載,在用戶登錄成功后所有控制器又要在登錄成功后衔蹲,重新加載一次網(wǎng)絡(luò)請求肢娘。浪費(fèi)性能,同時(shí)也增加了程序的復(fù)雜度舆驶。