你真的瞭解UITabBarController嗎?

来源:http://www.cnblogs.com/wujy/archive/2016/09/02/5832714.html
-Advertisement-
Play Games

一:首先查看一下關於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裡面的內容;

知識點1iOS 點擊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

知識點1tabBarItem相關屬性運用

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:

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • [1]滾動寬高 [2]頁面尺寸 [3]滾動長度 [4]頁面滾動 [5]滾動方法 [6]滾動事件 ...
  • ExtJS的強大功能之一是提供了非常豐富的組件,包括grid(表格)、panel(面板)、form(表單)、button(按鈕)、progressBar(進度條)等等。 一個的ExtJS 4應用程式的UI界面,就是由一個或多個組件組成。 這裡將會介紹組件的分類、名稱、結構以及創建方式。 ...
  • 我們通過功能檢測技術對那些不確定因素進行逐一排除,為了避免讓瀏覽器報錯和性能原因。在原生中這是一種非常重要的開發方式。 ...
  • <hr>分割線<div>盒子的使用<strong>字體加粗<br>換行<del>字體刪除線<ol>有序列表 - <li><ul>無序列表 - <li><dl>自定義列表 : <dt> <dd>li+*+5+TAB=5個<li><iframe src="xxxxxxxx" frameborder="1 ...
  • github地址:https://github.com/lily1010/vue_learn/tree/master/lesson03 一 實例 每個 Vue 實例都會代理其 data 對象里所有的屬性,改變data,vue實例同時改變,當然改變vue實例,data也同時改變,即 vue實例<=>d ...
  • clearfix定義如下: 方法:子節點設置了浮動,在其父節點上添加clearfix類便可達到清除浮動效果 參考:http://blog.sina.com.cn/s/blog_60b35e830101c1r8.html ...
  • 利用flex佈局的web移動端和react native的三欄佈局實現(react native佈局基礎) ...
  • 學習要點總結:PS導出圖片(PNG JPG) 導出後為PNG格式 PS導出圖層等比例調節大小 按住SHFIT鍵(PS)ctrl+或者- 放大縮小圖片測試html瀏覽器 谷歌 火狐 歐鵬 IE 解析模式:標準模式 混亂模式 非標準模式UTF-8 :支持中文HTML別名 根元素/:關閉標簽TAB 標簽快 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...