管理多個控制器,以不可變數(shù)組管理,而且創(chuàng)建時必須要全部指定所管理的多個視圖控制器,而且多個視圖控制器同時存在,沒有層次關(guān)系的視圖控制器(同時存在,互不干擾)空間不回收

子控制器

結(jié)構(gòu)
UITransitionView---存放當(dāng)前子控制器的view
UITabBar---導(dǎo)航條(在下方)高度為49;添加了幾個子控制器,底下的TabBar會被平分;能夠被點擊,切換到對應(yīng)的view。
UITabBar上最多可以顯示5個Tab,當(dāng)我們往UITabBarController中添加超過的viewController超過5個時候,最后一個一個就會自動變成省略號。
基本使用
Info.plist 去掉main
添加視圖:UIWindow—>UITabBarcontroller—>UINavigationController— >UIViewController,必須按此順序添加

注意:以上標(biāo)題不這樣設(shè)
添加多個子控制器

PS:可以有導(dǎo)航控制器,即TabBarControler也可以控制導(dǎo)航控制器
PS:TabBarControler默認(rèn)顯示第一個子控制器的view,但是可以改
tabVC.selectedIndex = 1 ;
其中所賦的置是子控制器的索引,從0開始為第一個。
管理原則
- UITabBarController會一次性初始化所有子控制器,但是默認(rèn)只加載第一個控制器視圖,其他視圖控制器只初始化,默認(rèn)不會加載。只有當(dāng)需要顯示的時候才loadView加載。
- 子控制器加載后會存在內(nèi)存中,下次直接顯示,切換子控制器不會銷毀之前顯示的子控制器。只是所顯示的view會先從屏幕移除,再添加。
- 每個視圖控制器都有一個tabBarController屬性,通過它可以訪問所在的TabBarController,而且對于TabBarController的直接子視圖,其tabBarController等于parentViewController。
-
每個視圖控制器都有一個tabBarItem屬性,通過它控制視圖在UITabBarController的tabBar中的顯示信息。
QQ.png
設(shè)置TabBar內(nèi)容

UITabBarButton
要顯示什么內(nèi)容,由對應(yīng)的子控制器的tabBarItem屬性決定。

如:

UITabBar有一些方法是可以改變自身狀態(tài),但是對于UITabBarController自帶的tabBar,不能直接去修改其狀態(tài),否則將會拋出異常
切換選中的子控制器
1.通過selectedIndex屬性可以獲得當(dāng)前選中的viewController。設(shè)置該屬性,可以顯示viewControllers中對應(yīng)index的viewController。
2.通過selectedViewController屬性可以獲取到當(dāng)前顯示的viewController。所以,通過設(shè)置該屬性可以設(shè)置當(dāng)前選中的viewController,同時更新selectedIndex。
主流框架
以TabBarControler作為根控制器,控制多個導(dǎo)航控制器及其view

首先在storybord中刪除默認(rèn)的viewcontroler,拖一個tabBarControler,設(shè)為默認(rèn)控制器
Modal切換方式(從底部向上出現(xiàn),直到覆蓋這個view)

presentViewControler:方法
第一個參數(shù)為即將要出現(xiàn)的控制器,第二個參數(shù)可以設(shè)置動畫效果,第三個參數(shù)表示,當(dāng)modal完成時做什么事(可以為nil)。

PS:當(dāng)modal時,先移除當(dāng)前的view,然后把即將出現(xiàn)的view添加到窗口。
dismissViewControler:方法
一般用當(dāng)前控制器調(diào)用此方法,讓自己關(guān)閉掉
自定義TabBar
新建一個類,繼承自UIView。
在.h中聲明模型,保存TabBar子控件的內(nèi)容(圖片,文字)
@property(nonatomic ,strong) NSArray *items; //模型
在模型的set方法中添加子控件(一般是button),并設(shè)置子控件的內(nèi)容
-(void)setItems:(NSArray *)items{
_items = items;
for(int i = 0;i < self.items.count ; i++){
//添加子控件
UIButton *btn = [[UIButton alloc] init];
[self addSubview:btn];
//設(shè)置子控件btn的內(nèi)容
UITabBarItem *tbItem = self.items[i];
[btn setImage:tbItem.image forState:UIControlStateNormal];
[btn setImage:tbItem.selectedImage forState:UIControlStateSelected];
// [btn setBackgroundImage:tbItem.image forState:UIControlStateNormal]; 設(shè)為背景圖片,能夠占滿btn、
// [btn setBackgroundImage:tbItem.selectedImage forState:UIControlStateSelected];
//監(jiān)聽子控件btn,當(dāng)按下就選中
[btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchDown];
}
}
在layoutSubViews方法中布局子控件
-(void)layoutSubviews{
[super layoutSubviews];
CGFloat btnX = 0;
CGFloat btnY = 0;
CGFloat btnW = self.frame.size.width / self.subviews.count;
CGFloat btnH = self.frame.size.height;
int i = 0;
for(UIButton *btn in self.subviews){
btn.tag = i;
btnX = i * btnW;
btn.frame = CGRectMake(btnX, btnY, btnW, btnH);
if(i ==0 )
[self btnClick:btn]; //默認(rèn)初始時,選中第一個按鈕
i++;
}
}
實現(xiàn)控制器的切換
原理:自身不能做切換,只有控制器才能切換-->通過代理,通知外面的控制器(TabBarVC),切換子控制器-->利用selectedIndex屬性實現(xiàn)切換-->由監(jiān)聽子控件(button)的點擊,其tag與selectedIndex相對應(yīng)。
設(shè)置代理:在.h中聲明
//設(shè)置代理
@class PDTabBar;
@protocol PDTabBarDelegate <NSObject>
-(void)tabBar:(PDTabBar *)tabBar index:(NSInteger)index; //代理方法
@end
@interface PDTabBar : UIView
@property(nonatomic,weak) id<PDTabBarDelegate> delegate; //聲明代理
@end
PS:代理方法在TabBar控制器中具體實現(xiàn)
-(void)tabBar:(PDTabBar *)tabBar index:(NSInteger)index{
self.selectedIndex = index; //傳遞了tag,作為index,實現(xiàn)切換
}
PS:必須遵守它的協(xié)議<PDTabBarDelegate>,并將自己設(shè)為它的代理對象
子控件button的監(jiān)聽方法
-(void)btnClick:(UIButton *)btn{
//3步曲( 先聲明一個 選中按鈕 屬性 )
self.selectedBtn.selected = NO; //取消上次選中
btn.selected = YES; //選中當(dāng)前點擊的按鈕
self.selectedBtn = btn; //記錄之
//調(diào)用代理方法,通知外面切換子控制器
if([self.delegate respondsToSelector:@selector(tabBar:index:)]){
[self.delegate tabBar:self index:btn.tag]; //調(diào)用代理方法,把tag作為參數(shù)傳遞出去
}
}
至此,自定義TabBar完成,外界(在TabBarController中)基本使用如下:
使用自定義TabBar
兩種選擇:一是移除系統(tǒng)的TabBar,二是只移除系統(tǒng)TabBar的子控件
1.移除系統(tǒng)TabBar(缺點:失去系統(tǒng)自帶的滑動返回功能)
[self.tabBar removeFromSuperview]; //先移除
PDTabBar *newTabBar = [[PDTabBar alloc] init]; //創(chuàng)建自定義TabBar
newTabBar.items = self.items; //把外界數(shù)據(jù)模型 傳遞到 自定義TabBar的模型數(shù)組里。(此時調(diào)用了items的set方法(同時添加了子控件)
[self.view addSubview:newTabBar]; //添加到控制器的view上
newTabBar.frame = self.tabBar.frame; //布局 ( 此時 self.tabBar還沒有被銷毀 )
newTabBar.backgroundColor = [UIColor blackColor];
數(shù)據(jù):在設(shè)置TabBar內(nèi)容時,把TabBar子控件的內(nèi)容傳遞到模型
VC.tabBarItem.image = image;
VC.tabBarItem.selectedImage = selectImg;
VC.tabBarItem.title = title;
[self.items addObject:VC.tabBarItem];
隱藏底部TabBar
2.只移除系統(tǒng)TabBar的子控件(仍有滑動返回功能)
創(chuàng)建并添加
PDTabBar *newTabBar = [[PDTabBar alloc] init]; //創(chuàng)建自定義TabBar
newTabBar.items = self.items;
[self.tabBar addSubview:newTabBar]; //添加到系統(tǒng)TabBar上面,此時自定義的TabBar作為系統(tǒng)TabBar的一個子控件
newTabBar.frame = self.tabBar.bounds; //布局,要用bounds,不能用frame
newTabBar.backgroundColor = [UIColor blackColor];
移除系統(tǒng)TabBar的子控件
要在viewWillAppear方法中移除系統(tǒng)的TabBar的子控件UITabBarButton(私有),因為在viewDidLoad中子控件還沒有加載完
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
//遍歷TabBar的子控件
for(UIView *view in self.tabBar.subviews){
if(![view isKindOfClass:[PDTabBar class]])
[view removeFromSuperview];
}
}
執(zhí)行以上操作后,系統(tǒng)TabBar中 只有自定義的TabBar
隱藏底部TabBar
在storybord中設(shè)置將要顯示的控制器(非根控制器)的Hide Bottom Bar on Push(勾選)
或者采用代碼方法,在所要跳轉(zhuǎn)的控制器中:
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
self.tabBarController.tabBar.hidden = YES; //切換后,隱藏底部TabBar
}
