一兢卵、UITabBarController程帕,繼承并封裝UIViewController,原理是每次點擊之后先隱藏上一個記住的ViewController
UIViewController *viewController = _viewControllers[index];
if (viewController.parentViewController) {
[viewController willMoveToParentViewController:nil];
[viewController.view removeFromSuperview];
[viewController removeFromParentViewController];
}
再insert一個新的
UIViewController *viewController = _viewControllers[index];
[self addChildViewController:viewController];
viewController.view.frame = CGRectMake(0, 0, CGRectGetWidth(self.view.frame), CGRectGetHeight(self.view.frame));
if (self.tabBar) {
[self.view insertSubview:viewController.view belowSubview:self.tabBar];
}
else {
[self.view addSubview:viewController.view];
}
[self didMoveToParentViewController:viewController];
UITabBarController主要用來管理你提供的content view controllers,而每一個 content view controller則負責(zé)管理自己的view層級關(guān)系授账,通常痕鳍,當你的程序想要提供一些平行(同一個等級的)的不同界面径簿,而恰好這些界面使用到的數(shù)據(jù)是一類的饭冬,或者功能是一個系列的,那 tab bar interface 是非常有用的. 在這樣的 tab bar interface界面中茎用,你可以設(shè)置許多的 tab 遣总,每一個 tab則一定要指定一個content view controller,當某個tab被點擊時,UITabBarController就會選中該tab并且顯示該viewController所持有的content view
觀察上圖轨功,最下面的那個Tab bar,這是由UITabBarController自己負責(zé)維護的旭斥,就像UINavigation Bar是由UINavigationController負責(zé)維護一樣,不建議被修改古涧,但如果實在需要改變的話垂券,只能通過UITabBarController提供的方法去修改。
你有沒有發(fā)現(xiàn)羡滑,絕大多數(shù)的iOS程序菇爪,如果他用到了UITabBarController,那么他的外觀就像上圖柒昏,Tab bar默認在下面凳宙,但有時我們又希望將他顯示到最上面去,就像android的聯(lián)系人程序一樣职祷,其實只要幾句代碼就行了:
self.tabBar.frame = CGRect(x: 0, y: 20, width: UIScreen.main.bounds.size.width, height: 44) ```
下方TabBar條繼承UIView,封裝成UITabBar氏涩,UITabBar的高度為49,UITabBarButton在UITabBar中得位置是均分的堪旧。


二削葱、一個標準的 tab bar interface 通常由下列對象組成:
1.一個 UITabBarController 對象
2.每一個tab 都必須有一個content view controller(所以UITabBarController有一個屬性是viewControllers)
3.一個可選的delegate對象
通常而言,UITabBarController一般作為應(yīng)用程序的rootViewController,而且它不能作為UINavigationController的rootViewController淳梦。從xib的Embed in功能也能看出不建議UITabBarController再套一個UINavigationController析砸,下面是apple官方給的一個圖片

從這張圖可以看到:最右邊的Assembled views是呈現(xiàn)給用戶的集成好的界面,它左邊的Window是最底層的窗口爆袍,重點來了首繁,再往左作郭,是Tab bar view,Tab bar view的上方是Navigation view弦疮,最后是用戶定制的視圖夹攒。
看完這個,代碼就應(yīng)該很好寫了胁塞,我們需要把Navigation view加到 Tab bar view的內(nèi)容上去咏尝,Tab bar view再加到Window上去。就是Window套UITabBarController啸罢,UITabBarController套UINavigationController, UINavigationController套UIViewController编检。
初始化
let A = AViewController()
let B = BViewController()
let C = CViewController()
let D = DViewController()
let E = EViewController()
let F = FViewController()
let list = [A,B,C,D,E,F]
var vcs = UIViewController
for i in 0 ... 5{
// 每個VC外套個Nav 也可不用
vcs.append(UINavigationController(rootViewController: list[i]))
}
A.tabBarItem = UITabBarItem(title: "A", image: UIImage.init(named: "tab_home_n"), selectedImage: UIImage.init(named: "tab_home_s"))
B.tabBarItem = UITabBarItem(title: "B", image: UIImage.init(named: "tab_inspiration_n"), selectedImage: UIImage.init(named: "tab_inspiration_s"))
C.tabBarItem = UITabBarItem(title: "C", image: UIImage.init(named: "tab_me_n"), selectedImage: UIImage.init(named: "tab_me_s"))
D.tabBarItem = UITabBarItem(title: "D", image: UIImage.init(named: "tab_purchase_n"), selectedImage: UIImage.init(named: "tab_purchase_s"))
E.tabBarItem = UITabBarItem(title: "E", image: UIImage.init(named: "tab_search_n"), selectedImage: UIImage.init(named: "tab_search_s"))
F.tabBarItem = UITabBarItem(title: "F", image: UIImage.init(named: "tab_me_n_u"), selectedImage: UIImage.init(named: "tab_me_s_u"))
self.selectedIndex = 2;
C.tabBarItem.badgeValue = "3"
self.viewControllers = vcs
// self.moreNavigationController.navigationBar.isHidden = true
// self.tabBar.frame = CGRect(x: 0, y: 20, width: UIScreen.main.bounds.size.width, height: 44);
其中self繼承自UITabBarController。圖片一般ipad在60*60扰才,iPhone在30*30左右允懂。
三、 再來看下面這張圖衩匣,它描繪了UITabBarController和它的屬性viewControllers蕾总、customizableViewControllers和selectedViewController等的關(guān)系

如果你的viewControllers屬性添加了多于五個的items,那tab bar controller將會自動插入一個特殊的view controller,稱為 More view controller,該 controller 將會負責(zé)管理多于的items,這個More view controller提供一個自定義的界面琅捏,用table的方式呈現(xiàn)多余的view controller生百,并且view controller的數(shù)量是不限制的。對于這個more view controller ,UITabBarController 通過一個屬性----moreNavigationController持有它的引用柄延,但看名字就知道他是一個UINavigationController對象置侍,所有我們可以修改它的一些屬性,如:
self.tabBar.frame = CGRect(x: 0, y: 20, width: UIScreen.main.bounds.size.width, height: 44); ```
當然拦焚,如不是必須,最好不要修改它杠输。
在tab bar interface創(chuàng)建好后赎败,我們可以用代碼動態(tài)的修改它,如:增加或刪除tab項蠢甲,對于這種操作僵刮,通常我們需要重新指派UITabBarController的viewConrollers屬性來進行,有人可能要問了鹦牛,為什么要重新指派搞糕,viewController不是一個數(shù)組嗎,不能直接通過數(shù)組的remove方法直接刪除嗎曼追,可別忘了窍仰,這個屬性的類型是個NSArray,不能進行刪除礼殊,添加的驹吮。我們知道针史,當tab bar interface界面顯示后,我們只能在某一時刻操作一個界面碟狞,因此啄枕,修改viewControllers屬性必須在某個content viewController中完成,我們可以通過UIViewController的屬性 tabBarController來獲得UITabBarController的引用族沃,就像獲得UINavigationController的引用一樣:
四频祝、 代理方法
UITabBarController是否能旋轉(zhuǎn)呢?那要看它的那些viewControllers了脆淹,如果在viewControllers中只要有一個viewController不支持某個方向的旋轉(zhuǎn)常空,那UITabBarControlelr就也不能旋轉(zhuǎn)到該方向
當你點擊某個tab項時,它對應(yīng)的content viewController會得到顯示未辆,但有時也許我們就是不希望某個被你點擊的view得到顯示窟绷,如:某個viewController所需的數(shù)據(jù)還沒有完成加載,或者必須等某個登陸界面 完成登陸后才能激活其他viewController咐柜,此時你可以實現(xiàn)UITabBarControllerDelgate中的方法
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool { }
通過設(shè)置返回值來禁止某個viewController能否被選中兼蜈。
當然你也可以通過代碼手動去選擇某個viewController,只要設(shè)置UITabBarController的屬性selectedViewController 或者 selectedIndex(從0開始),但此時代理的方法是無效的拙友,也就是說为狸,如果你通過代碼來選中某個viewController的話,則肯定是可以選中的遗契。辐棒。。
didSelect方法 :當你選中某個tab 項時調(diào)用牍蜂,我們可以在這里做一些操作漾根,如隱藏狀態(tài)欄,導(dǎo)航欄什么的
willBeginCustomizingViewControllers:當點擊more后出現(xiàn)moreNavigationController畫面時鲫竞,點擊那個edit按鈕時觸發(fā)
五辐怕、UITabBarController還允許你對viewControllers進行排序,你可以使任意一個viewController出現(xiàn)在第一個tab項中从绘,上面我們有提到moreNavigationController,當tabs超過5個時寄疏,也就是viewControllers的個數(shù)超過5個時,最后一個的tab item默認為more僵井,然后那些沒能顯示在tab上的viewController便可通過moreNavigationController以列表的形勢顯示陕截,那是不是那些沒能在tab上顯示的viewController就永遠只能在moreNavigationController的列表中顯示了?批什?當然不是农曲,當我么點擊more tab時會出現(xiàn)下面圖6的界面,然后再點擊navigationBar左邊的編輯按鈕時會出現(xiàn)圖7驻债,此時你可以把這些顯示的tab直接拉到下面的 tab bar中朋蔫,從而達到自定義tab的功能
那如果我希望某個viewController一直在tab上顯示罚渐,二不希望用戶將其排列到more tab中去,那該怎么辦呢驯妄。荷并。。青扔。 UITabBarController有個屬customizableViewControllers由它來決定哪些viewController允許重排列源织。。不過這里要注意了微猖,默認情況下customizableViewControllers 和 viewControllers屬性包含的內(nèi)容是一樣的谈息,你可以手動設(shè)置它為viewControllers的字集(只能是字集),但當你重新更新了viewControllers時凛剥,customizableViewControllers又會默認和viewControllers相等
六侠仇、 使用場景
1.作為window的root view controller
2.作為 split view interface(iPad專有界面,不知道的可以百度下)中的其中一個一個view controller
3.作為modal view使用
4.作為UIPopoverController(iPad專有)的content view