UITabBarController

一、UITabBarController,繼承并封裝UIViewController,原理是每次點(diǎn)擊之后先隱藏上一個(gè)記住的ViewController

UIViewController *viewController = _viewControllers[index];
    if (viewController.parentViewController) {
        [viewController willMoveToParentViewController:nil];
        [viewController.view removeFromSuperview];
        [viewController removeFromParentViewController];
    }

再insert一個(gè)新的

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主要用來(lái)管理你提供的content view controllers,而每一個(gè) content view controller則負(fù)責(zé)管理自己的view層級(jí)關(guān)系,通常,當(dāng)你的程序想要提供一些平行(同一個(gè)等級(jí)的)的不同界面,而恰好這些界面使用到的數(shù)據(jù)是一類(lèi)的,或者功能是一個(gè)系列的,那 tab bar interface 是非常有用的. 在這樣的 tab bar interface界面中,你可以設(shè)置許多的 tab ,每一個(gè) tab則一定要指定一個(gè)content view controller,當(dāng)某個(gè)tab被點(diǎn)擊時(shí),UITabBarController就會(huì)選中該tab并且顯示該viewController所持有的content view


1.jpg

觀察上圖,最下面的那個(gè)Tab bar,這是由UITabBarController自己負(fù)責(zé)維護(hù)的,就像UINavigation Bar是由UINavigationController負(fù)責(zé)維護(hù)一樣,不建議被修改,但如果實(shí)在需要改變的話(huà),只能通過(guò)UITabBarController提供的方法去修改。
  你有沒(méi)有發(fā)現(xiàn),絕大多數(shù)的iOS程序,如果他用到了UITabBarController,那么他的外觀就像上圖,Tab bar默認(rèn)在下面,但有時(shí)我們又希望將他顯示到最上面去,就像android的聯(lián)系人程序一樣,其實(shí)只要幾句代碼就行了:

self.tabBar.frame = CGRect(x: 0, y: 20, width: UIScreen.main.bounds.size.width, height: 44)  ```
  下方TabBar條繼承UIView,封裝成UITabBar,UITabBar的高度為49,UITabBarButton在UITabBar中得位置是均分的。
![2.png](http://upload-images.jianshu.io/upload_images/1744186-eb897b3449a36bfd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![3.png](http://upload-images.jianshu.io/upload_images/1744186-7ef50ff2c9c1bcad.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

二、一個(gè)標(biāo)準(zhǔn)的 tab bar interface 通常由下列對(duì)象組成:
1.一個(gè) UITabBarController 對(duì)象
2.每一個(gè)tab 都必須有一個(gè)content view controller(所以UITabBarController有一個(gè)屬性是viewControllers)
3.一個(gè)可選的delegate對(duì)象
通常而言,UITabBarController一般作為應(yīng)用程序的rootViewController,而且它不能作為UINavigationController的rootViewController。從xib的Embed in功能也能看出不建議UITabBarController再套一個(gè)UINavigationController,下面是apple官方給的一個(gè)圖片
![4.jpg](http://upload-images.jianshu.io/upload_images/1744186-1c8b50309dedae02.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

從這張圖可以看到:最右邊的Assembled views是呈現(xiàn)給用戶(hù)的集成好的界面,它左邊的Window是最底層的窗口,重點(diǎn)來(lái)了,再往左,是Tab bar view,Tab bar view的上方是Navigation view,最后是用戶(hù)定制的視圖。
看完這個(gè),代碼就應(yīng)該很好寫(xiě)了,我們需要把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{
// 每個(gè)VC外套個(gè)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左右。

三、 再來(lái)看下面這張圖,它描繪了UITabBarController和它的屬性viewControllers、customizableViewControllers和selectedViewController等的關(guān)系
![5.jpg](http://upload-images.jianshu.io/upload_images/1744186-15fccac9346b7d5d.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
  如果你的viewControllers屬性添加了多于五個(gè)的items,那tab bar controller將會(huì)自動(dòng)插入一個(gè)特殊的view controller,稱(chēng)為 More view controller,該 controller 將會(huì)負(fù)責(zé)管理多于的items,這個(gè)More view controller提供一個(gè)自定義的界面,用table的方式呈現(xiàn)多余的view controller,并且view controller的數(shù)量是不限制的。對(duì)于這個(gè)more view  controller ,UITabBarController 通過(guò)一個(gè)屬性----moreNavigationController持有它的引用,但看名字就知道他是一個(gè)UINavigationController對(duì)象,所有我們可以修改它的一些屬性,如:

self.tabBar.frame = CGRect(x: 0, y: 20, width: UIScreen.main.bounds.size.width, height: 44); ```
當(dāng)然,如不是必須,最好不要修改它。
在tab bar interface創(chuàng)建好后,我們可以用代碼動(dòng)態(tài)的修改它,如:增加或刪除tab項(xiàng),對(duì)于這種操作,通常我們需要重新指派UITabBarController的viewConrollers屬性來(lái)進(jìn)行,有人可能要問(wèn)了,為什么要重新指派,viewController不是一個(gè)數(shù)組嗎,不能直接通過(guò)數(shù)組的remove方法直接刪除嗎,可別忘了,這個(gè)屬性的類(lèi)型是個(gè)NSArray,不能進(jìn)行刪除,添加的。我們知道,當(dāng)tab bar interface界面顯示后,我們只能在某一時(shí)刻操作一個(gè)界面,因此,修改viewControllers屬性必須在某個(gè)content viewController中完成,我們可以通過(guò)UIViewController的屬性 tabBarController來(lái)獲得UITabBarController的引用,就像獲得UINavigationController的引用一樣:

四、 代理方法
UITabBarController是否能旋轉(zhuǎn)呢?那要看它的那些viewControllers了,如果在viewControllers中只要有一個(gè)viewController不支持某個(gè)方向的旋轉(zhuǎn),那UITabBarControlelr就也不能旋轉(zhuǎn)到該方向
當(dāng)你點(diǎn)擊某個(gè)tab項(xiàng)時(shí),它對(duì)應(yīng)的content viewController會(huì)得到顯示,但有時(shí)也許我們就是不希望某個(gè)被你點(diǎn)擊的view得到顯示,如:某個(gè)viewController所需的數(shù)據(jù)還沒(méi)有完成加載,或者必須等某個(gè)登陸界面 完成登陸后才能激活其他viewController,此時(shí)你可以實(shí)現(xiàn)UITabBarControllerDelgate中的方法
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool { }
通過(guò)設(shè)置返回值來(lái)禁止某個(gè)viewController能否被選中。
當(dāng)然你也可以通過(guò)代碼手動(dòng)去選擇某個(gè)viewController,只要設(shè)置UITabBarController的屬性selectedViewController 或者 selectedIndex(從0開(kāi)始),但此時(shí)代理的方法是無(wú)效的,也就是說(shuō),如果你通過(guò)代碼來(lái)選中某個(gè)viewController的話(huà),則肯定是可以選中的。。。
didSelect方法 :當(dāng)你選中某個(gè)tab 項(xiàng)時(shí)調(diào)用,我們可以在這里做一些操作,如隱藏狀態(tài)欄,導(dǎo)航欄什么的
willBeginCustomizingViewControllers:當(dāng)點(diǎn)擊more后出現(xiàn)moreNavigationController畫(huà)面時(shí),點(diǎn)擊那個(gè)edit按鈕時(shí)觸發(fā)

五、UITabBarController還允許你對(duì)viewControllers進(jìn)行排序,你可以使任意一個(gè)viewController出現(xiàn)在第一個(gè)tab項(xiàng)中,上面我們有提到moreNavigationController,當(dāng)tabs超過(guò)5個(gè)時(shí),也就是viewControllers的個(gè)數(shù)超過(guò)5個(gè)時(shí),最后一個(gè)的tab item默認(rèn)為more,然后那些沒(méi)能顯示在tab上的viewController便可通過(guò)moreNavigationController以列表的形勢(shì)顯示,那是不是那些沒(méi)能在tab上顯示的viewController就永遠(yuǎn)只能在moreNavigationController的列表中顯示了??當(dāng)然不是,當(dāng)我么點(diǎn)擊more tab時(shí)會(huì)出現(xiàn)下面圖6的界面,然后再點(diǎn)擊navigationBar左邊的編輯按鈕時(shí)會(huì)出現(xiàn)圖7,此時(shí)你可以把這些顯示的tab直接拉到下面的 tab bar中,從而達(dá)到自定義tab的功能

6.png

7.png

那如果我希望某個(gè)viewController一直在tab上顯示,二不希望用戶(hù)將其排列到more tab中去,那該怎么辦呢。。。。 UITabBarController有個(gè)屬customizableViewControllers由它來(lái)決定哪些viewController允許重排列。。不過(guò)這里要注意了,默認(rèn)情況下customizableViewControllers 和 viewControllers屬性包含的內(nèi)容是一樣的,你可以手動(dòng)設(shè)置它為viewControllers的字集(只能是字集),但當(dāng)你重新更新了viewControllers時(shí),customizableViewControllers又會(huì)默認(rèn)和viewControllers相等

六、 使用場(chǎng)景
1.作為window的root view controller
2.作為 split view interface(iPad專(zhuān)有界面,不知道的可以百度下)中的其中一個(gè)一個(gè)view controller
3.作為modal view使用
4.作為UIPopoverController(iPad專(zhuān)有)的content view

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容