iOS-UITabBarController詳細(xì)總結(jié)

一、UITabBarController以其相關(guān)控件之間的關(guān)系

@interface UITabBarController : UIViewController

@property(nonatomic,readonly) UITabBar *tabBar;

@interface UITabBar : UIView

@property(nullable, nonatomic, copy) NSArray *items;

@interface UITabBarItem : UIBarItem

@property(nullable, nonatomic,strong) UIImage *selectedImage;

@property(nullable, nonatomic, copy) NSString *badgeValue;

UIBarItem

一個(gè)可以放置在Bar之上的所有小控件類的抽象類,可以設(shè)置標(biāo)題锦募,圖片等

UITabBarItem

繼承UIBarItem,增加了selected协饲、unselected時(shí)不同狀態(tài)以及badgeValue等屬性畏腕,相當(dāng)于放在TabBar上的特殊“button”

UITabBar

NavigaitonBar就是底部的選擇欄 主要對(duì)UITabBarItem進(jìn)行管理 并負(fù)責(zé)展示底部選擇欄的外觀背景

UITabBarController

包含了viewcontrollers、tabBar等

關(guān)系綜述

1茉稠、UITabBarController繼承UIViewController,是一個(gè)Container把夸;

2而线、UITabBarController擁有一個(gè)readonly的TabBar,TabBar擁有一到多個(gè)TabBarItem恋日;

3膀篮、每一個(gè)TabBarItem需要關(guān)聯(lián)一個(gè)UIViewController;

這里可以參考IOS-UINavigationController詳解關(guān)于UINavigationController等相關(guān)控件之間的關(guān)系綜述岂膳,UITabBarController和UINavigationController相似誓竿。

2、UITabBarController及其相關(guān)控件的屬性和方法

1.UITabBarItem

UITabBarItem時(shí)一個(gè)抽象類谈截,主要負(fù)責(zé)設(shè)置底部每個(gè)Item的文字和圖片等屬性筷屡。

typedef NS_ENUM(NSInteger, UITabBarSystemItem) {

UITabBarSystemItemMore,

UITabBarSystemItemFavorites,

UITabBarSystemItemFeatured,

UITabBarSystemItemTopRated,

UITabBarSystemItemRecents,

UITabBarSystemItemContacts,

UITabBarSystemItemHistory,

UITabBarSystemItemBookmarks,

UITabBarSystemItemSearch,

UITabBarSystemItemDownloads,

UITabBarSystemItemMostRecent,

UITabBarSystemItemMostViewed,

};

NS_CLASS_AVAILABLE_IOS(2_0) @interface UITabBarItem : UIBarItem

//初始化方法

- (instancetype)init;

- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder;

- (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;

//選中的圖片

@property(nullable, nonatomic,strong) UIImage *selectedImage NS_AVAILABLE_IOS(7_0);

//角標(biāo)

@property(nullable, nonatomic, copy) NSString *badgeValue;

//_____________________________________________IOS7廢除的方法(忽略)______________________________________________________

- (void)setFinishedSelectedImage:(nullable UIImage *)selectedImage withFinishedUnselectedImage:(nullable UIImage *)unselectedImage NS_DEPRECATED_IOS(5_0,7_0);

- (nullable UIImage *)finishedSelectedImage NS_DEPRECATED_IOS(5_0,7_0);

- (nullable UIImage *)finishedUnselectedImage NS_DEPRECATED_IOS(5_0,7_0);

//___________________________________________________________________________________________________

//title的偏移量

@property (nonatomic, readwrite, assign) UIOffset titlePositionAdjustment;

//_____________________________________________IOS10新增的屬性和方法______________________________________________________

//角標(biāo)顏色

@property (nonatomic, readwrite, copy, nullable) UIColor *badgeColor;

//角標(biāo)設(shè)置富文本

- (void)setBadgeTextAttributes:(nullable NSDictionary *)textAttributes forState:(UIControlState)state;

- (nullable NSDictionary *)badgeTextAttributesForState:(UIControlState)state;

//___________________________________________________________________________________________________

@end

總結(jié)

通過初始化方法可以設(shè)置title,image簸喂,selectedImage等展示的元素毙死。

badgeValue屬性可以在Item的右上角顯示一個(gè)數(shù)字角標(biāo)。

titlePositionAdjustment設(shè)置文字的偏移量

iOS10之后喻鳄,可以通過badgeColor扼倘,setBadgeTextAttributes等設(shè)置角標(biāo)的背景色,富文本的角標(biāo)數(shù)值除呵。

當(dāng)UITabBar上的UITabBarItem>=6個(gè)時(shí)再菊,底部的UITabBar左側(cè)會(huì)顯示一個(gè)More的Item。

2.UITabBar

一個(gè)UITabBarController只有一個(gè)TabBar颜曾。

NS_CLASS_AVAILABLE_IOS(2_0) @interface UITabBar : UIView

//代理

@property(nullable, nonatomic, weak) id delegate;

//get/set UITabBarItems 默認(rèn)是nil 改變時(shí)沒有動(dòng)畫效果 按順序展示

@property(nullable, nonatomic, copy) NSArray *items;

//選中的item

@property(nullable, nonatomic, weak) UITabBarItem *selectedItem;

//設(shè)置Items

- (void)setItems:(nullable NSArray *)items animated:(BOOL)animated;

- (void)beginCustomizingItems:(NSArray *)items;

- (BOOL)endCustomizingAnimated:(BOOL)animated;

#if UIKIT_DEFINE_AS_PROPERTIES

@property(nonatomic, readonly, getter=isCustomizing) BOOL customizing;

#else

- (BOOL)isCustomizing;

#endif

//ios7之后,

@property(null_resettable, nonatomic, strong) UIColor *tintColor ;

@property(nullable, nonatomic, strong) UIColor *barTintColor ;

//未選中的Item的顏色 IOS10可用

@property (nonatomic, readwrite, copy, nullable) UIColor *unselectedItemTintColor;

//ios8后廢除 使用tintColor

@property(nullable, nonatomic, strong) UIColor *selectedImageTintColor(5_0,8_0);

//背景圖片

@property(nullable, nonatomic, strong) UIImage *backgroundImage;

@property(nullable, nonatomic, strong) UIImage *selectionIndicatorImage;

@property(nullable, nonatomic, strong) UIImage *shadowImage;

//item位置

@property(nonatomic) UITabBarItemPositioning itemPositioning;

//item寬度

@property(nonatomic) CGFloat itemWidth;

//item間隙

@property(nonatomic) CGFloat itemSpacing;

//樣式

@property(nonatomic) UIBarStyle barStyle;

//半透明

@property(nonatomic,getter=isTranslucent) BOOL translucent NS_AVAILABLE_IOS(7_0);

@end

以下是tabBar的代理方法纠拔,操作TabBar時(shí)的回調(diào),主要是對(duì)UITabBarItem的操作

@protocol UITabBarDelegate

@optional

/**

用戶選中某個(gè)UITabBarItem

*/

- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item;

//此四個(gè)代理方法是當(dāng)Items>=6個(gè)時(shí)泛啸,當(dāng)進(jìn)入More頁(yè)面時(shí)绿语,開始或結(jié)束Item編輯狀態(tài)的相關(guān)回調(diào)

- (void)tabBar:(UITabBar *)tabBar willBeginCustomizingItems:(NSArray *)items;

- (void)tabBar:(UITabBar *)tabBar didBeginCustomizingItems:(NSArray *)items;

- (void)tabBar:(UITabBar *)tabBar willEndCustomizingItems:(NSArray *)items changed:(BOOL)changed;

- (void)tabBar:(UITabBar *)tabBar didEndCustomizingItems:(NSArray *)items changed:(BOOL)changed;

@end

3.UITabBarController

NS_CLASS_AVAILABLE_IOS(2_0) @interface UITabBarController : UIViewController

//視圖控制器數(shù)組,這個(gè)屬性被賦值時(shí)候址,customizableViewControllers屬性的值與之一樣吕粹。

@property(nullable, nonatomic,copy) NSArray<__kindof UIViewController *> *viewControllers;

- (void)setViewControllers:(NSArray<__kindof UIViewController *> * __nullable)viewControllers animated:(BOOL)animated;

//當(dāng)前選中的視圖控制器

@property(nullable, nonatomic, assign) __kindof UIViewController *selectedViewController;

//與selectedViewController對(duì)應(yīng)

@property(nonatomic) NSUInteger selectedIndex;

//當(dāng)ViewController的數(shù)量>=6,TabBar會(huì)出現(xiàn)一個(gè)moreNavigationController管理多余的viewcontroller岗仑。readonly屬性

@property(nonatomic, readonly) UINavigationController *moreNavigationController;

//當(dāng)viewcontroller>=6時(shí),moreNavigationController右上方會(huì)有個(gè)edit按鈕匹耕,支持通過拖拽修改ViewController的順序,如若要屏蔽該功能荠雕,customizableViewControllers設(shè)置為nil即可稳其。

@property(nullable, nonatomic, copy) NSArray<__kindof UIViewController *> *customizableViewControllers;

//只讀屬性驶赏,為了配置UITabBarItem,應(yīng)該去修改ViewControllers屬性既鞠。

@property(nonatomic,readonly) UITabBar *tabBar;

//協(xié)議

@property(nullable, nonatomic,weak) id delegate;

@end

//should選中viewController? return YES 可以本選中煤傍, NO不可以被選中

- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController;

// 選中viewController后執(zhí)行的Action

- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController;

// 將要處于編輯狀態(tài)(即點(diǎn)擊MoreNavigationController的edit按鈕)

- (void)tabBarController:(UITabBarController *)tabBarController willBeginCustomizingViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers;

// MoreNavigationController will結(jié)束編輯狀態(tài)

- (void)tabBarController:(UITabBarController *)tabBarController willEndCustomizingViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers changed:(BOOL)changed;

//MoreNavigationController did結(jié)束編輯狀態(tài)

- (void)tabBarController:(UITabBarController *)tabBarController didEndCustomizingViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers changed:(BOOL)changed;

//UITabBarController支持的界面方向

- (UIInterfaceOrientationMask)tabBarControllerSupportedInterfaceOrientations:(UITabBarController *)tabBarController;

//對(duì)于將要展示的tabBarController 優(yōu)先選擇屏幕方向

- (UIInterfaceOrientation)tabBarControllerPreferredInterfaceOrientationForPresentation:(UITabBarController *)tabBarController;

//自定義轉(zhuǎn)場(chǎng)動(dòng)畫

- (nullable id )tabBarController:(UITabBarController *)tabBarController

interactionControllerForAnimationController: (id )animationController;

- (nullable id )tabBarController:(UITabBarController *)tabBarController

animationControllerForTransitionFromViewController:(UIViewController *)fromVC

toViewController:(UIViewController *)toVC;

@end

@interface UIViewController (UITabBarControllerItem)

@property(null_resettable, nonatomic, strong) UITabBarItem *tabBarItem;

@property(nullable, nonatomic, readonly, strong) UITabBarController *tabBarController;

@end

3、實(shí)際開發(fā)中的相關(guān)問題

1. UITabBar的背景顏色

1.直接設(shè)置背景顏色

//? ? self.tabBar.backgroundColor = [UIColor orangeColor];

//? ? [[UITabBar appearance] setBackgroundColor:[UIColor orangeColor]];

[[UITabBar appearance]setBarTintColor:[UIColor orangeColor]];

[UITabBar appearance].translucent = NO

注意:

1.前兩種設(shè)置背景顏色的方法是無(wú)效的嘱蛋。

2.tabBar是一個(gè)readonly屬性蚯姆,這里不能使用TabBarController.tabBar.barTintColor設(shè)置背景色。

前兩種方法是無(wú)效的洒敏。

3.這里設(shè)置tabBar的半透明屬性translucent設(shè)置為NO龄恋,默認(rèn)為YES,若保留半透明效果,設(shè)置的顏色會(huì)與正常的顏色有色差;

2.添加一個(gè)有顏色的View

UIView * view = [UIView new];

view.backgroundColor = [UIColor orangeColor];

view.frame = self.tabBar.bounds;

[[UITabBar appearance] insertSubview:view atIndex:0];

3.使用背景圖片

[[UITabBar appearance] setBackgroundImage:[UIImage imageNamed:@"tabBarBackgroundImage"]];

[UITabBar appearance].translucent = NO;

這里同樣需要設(shè)置translucent為NO

2. UITabBar的頂部的shadowImage

[[UITabBar appearance] setShadowImage:[UIImage new]];

[[UITabBar appearance] setBackgroundImage:[[UIImage alloc]init]];

同UINavigationBar一樣凶伙,需同時(shí)設(shè)置ShadowImage和BackgroundImage才能生效郭毕。

3.tabBarItem選中時(shí)的背景色

//? ? [UITabBar appearance].selectionIndicatorImage = [self drawTabBarItemBackgroundImageWithSize:size];

self.tabBar.selectionIndicatorImage = [self drawTabBarItemBackgroundImageWithSize:size];

此處可直接獲取TabBarController的tabBar直接設(shè)置selectionIndicatorImage。

獲取某背景顏色的image的方法可參考IOS-UINavigationController詳解相關(guān)方法函荣,注意圖片size要設(shè)置正確显押。

4.修改tabBarItem的文字、圖片顏色

tabBarItem偏竟,默認(rèn)狀態(tài)下煮落,選中狀態(tài)是藍(lán)色,未選中狀態(tài)下是灰色踊谋。選中狀態(tài)的Item的文字和圖片顏色可直接通過tintColor屬性修改

self.tabBar.tintColor = [UIColor yellowColor];

現(xiàn)實(shí)中蝉仇,往往都是現(xiàn)實(shí)圖片實(shí)際的顏色。我們可以通過自定義一個(gè)tabBarItem繼承UITabBarItem殖蚕,在initWithCoder方法添加以下代碼完成現(xiàn)實(shí)圖片實(shí)際顏色的效果轿衔。

-(id)initWithTitle:(NSString *)title image:(UIImage *)image selectedImage:(UIImage *)selectedImage{

if (self = [super initWithTitle:title image:image selectedImage:selectedImage]) {

self.image = [self.image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];

self.selectedImage = [self.selectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];

[self setTitleTextAttributes:@{NSForegroundColorAttributeName : [self mostColorWithImage:self.image]}

forState:UIControlStateNormal];

[self setTitleTextAttributes:@{NSForegroundColorAttributeName : [self mostColorWithImage:self.selectedImage]}

forState:UIControlStateSelected];

}

return self;

}

-(UIColor*)mostColorWithImage:(UIImage *)image

{

#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_6_1

int bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast;

#else

int bitmapInfo = kCGImageAlphaPremultipliedLast;

#endif

//第一步 先把圖片縮小 加快計(jì)算速度. 但越小結(jié)果誤差可能越大

CGSize thumbSize=CGSizeMake(50, 50);

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

CGContextRef context = CGBitmapContextCreate(NULL,

thumbSize.width,

thumbSize.height,

8,//bits per component

thumbSize.width*4,

colorSpace,

bitmapInfo);

CGRect drawRect = CGRectMake(0, 0, thumbSize.width, thumbSize.height);

CGContextDrawImage(context, drawRect, image.CGImage);

CGColorSpaceRelease(colorSpace);

//第二步 取每個(gè)點(diǎn)的像素值

unsigned char* data = CGBitmapContextGetData (context);

if (data == NULL) return nil;

NSCountedSet *cls = [NSCountedSet setWithCapacity:thumbSize.width*thumbSize.height];

for (int x=0; x

for (int y=0; y

int offset = 4*(x*y);

int red = data[offset];

int green = data[offset+1];

int blue = data[offset+2];

int alpha =? data[offset+3];

if (alpha != 255) continue;

NSArray *clr=@[@(red),@(green),@(blue),@(alpha)];

[cls addObject:clr];

}

}

CGContextRelease(context);

//第三步 找到出現(xiàn)次數(shù)最多的那個(gè)顏色

NSEnumerator *enumerator = [cls objectEnumerator];

NSArray *curColor = nil;

NSArray *MaxColor=nil;

NSUInteger MaxCount=0;

while ( (curColor = [enumerator nextObject]) != nil )

{

NSUInteger tmpCount = [cls countForObject:curColor];

if ( tmpCount < MaxCount ) continue;

MaxCount=tmpCount;

MaxColor=curColor;

}

return [UIColor colorWithRed:([MaxColor[0] intValue]/255.0f) green:([MaxColor[1] intValue]/255.0f) blue:([MaxColor[2] intValue]/255.0f) alpha:1.0 ];

}

iOS10之后新增了unselectedItemTintColor設(shè)置未選中狀態(tài)下的item顏色。配合tintColor可以達(dá)到我們需要的大部分效果睦疫。

5.修改TabBar的高度

在UITabBarController里重寫viewWillLayoutSubviews

- (void)viewWillLayoutSubviews {

CGRect tabFrame = self.tabBar.frame;

tabFrame.size.height = 59;

tabFrame.origin.y = self.view.bounds.size.height - 59;

self.tabBar.frame = tabFrame;

}

然后通過UITabBarItem的imageInsets和titlePositionAdjustment屬性調(diào)整圖片和文字的位置

for (UITabBarItem * item in self.tabBar.items) {

item.imageInsets = UIEdgeInsetsMake(8, 0, -8, 0);

}

[[UITabBarItem appearance]setTitlePositionAdjustment:UIOffsetMake(0, -8)];

6. 自定義UITabBarController

具體內(nèi)容參考:仿閑魚自定義Tabbar(純代碼)

參考文章

iOS UI Tab開發(fā)

UITabBarController的使用

UITabBarController害驹、TabBar背景顏色設(shè)置、TabBarItem顏色處理

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蛤育,一起剝皮案震驚了整個(gè)濱河市宛官,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瓦糕,老刑警劉巖底洗,帶你破解...
    沈念sama閱讀 206,013評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異咕娄,居然都是意外死亡亥揖,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)费变,“玉大人摧扇,你說我怎么就攤上這事≈科纾” “怎么了扛稽?”我有些...
    開封第一講書人閱讀 152,370評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)滑负。 經(jīng)常有香客問我庇绽,道長(zhǎng),這世上最難降的妖魔是什么橙困? 我笑而不...
    開封第一講書人閱讀 55,168評(píng)論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮耕餐,結(jié)果婚禮上凡傅,老公的妹妹穿的比我還像新娘。我一直安慰自己肠缔,他們只是感情好夏跷,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,153評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著明未,像睡著了一般槽华。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上趟妥,一...
    開封第一講書人閱讀 48,954評(píng)論 1 283
  • 那天猫态,我揣著相機(jī)與錄音,去河邊找鬼披摄。 笑死亲雪,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的疚膊。 我是一名探鬼主播义辕,決...
    沈念sama閱讀 38,271評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼寓盗!你這毒婦竟也來(lái)了灌砖?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,916評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤傀蚌,失蹤者是張志新(化名)和其女友劉穎基显,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體喳张,經(jīng)...
    沈念sama閱讀 43,382評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡续镇,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,877評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了销部。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片摸航。...
    茶點(diǎn)故事閱讀 37,989評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡制跟,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出酱虎,到底是詐尸還是另有隱情雨膨,我是刑警寧澤,帶...
    沈念sama閱讀 33,624評(píng)論 4 322
  • 正文 年R本政府宣布读串,位于F島的核電站聊记,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏恢暖。R本人自食惡果不足惜排监,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,209評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望杰捂。 院中可真熱鬧舆床,春花似錦、人聲如沸嫁佳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,199評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蒿往。三九已至盛垦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間瓤漏,已是汗流浹背腾夯。 一陣腳步聲響...
    開封第一講書人閱讀 31,418評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留赌蔑,地道東北人俯在。 一個(gè)月前我還...
    沈念sama閱讀 45,401評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像娃惯,于是被迫代替她去往敵國(guó)和親跷乐。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,700評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容