欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解iOS自定義UITabBar與布局

 更新時(shí)間:2018年02月08日 15:53:27   投稿:laozhang  
本篇文章給大家詳細(xì)分析了iOS自定義UITabBar與布局的實(shí)際操作過(guò)程以及相關(guān)代碼分享,一起學(xué)習(xí)下。

在小編整理過(guò)的文章iOS項(xiàng)目基本框架搭建中,我們?cè)敿?xì)說(shuō)明了如何對(duì)TabBarItem的圖片屬性以及文字屬性進(jìn)行一些自定義配置。但是,很多時(shí)候,我們需要修改TabBarItem的圖片和文字屬性之外,還需要自定義TabBarItem的位置,這樣系統(tǒng)自帶的TabBar的樣式并不能滿足我們的項(xiàng)目需求,所以我們需要對(duì)系統(tǒng)的UITabBar進(jìn)行自定義,以達(dá)到我們的項(xiàng)目需求。例如新浪微博App的底部tab的item就無(wú)法用自帶的TabBarItem進(jìn)行實(shí)現(xiàn),最中間那個(gè)【+】發(fā)布微博并不是用來(lái)切換tab的,而是在當(dāng)前的頁(yè)面上覆蓋一個(gè)編輯發(fā)布頁(yè)面,發(fā)布完成或者取消發(fā)布之后又回到之前的頁(yè)面,并沒(méi)有進(jìn)行切換,這時(shí)候我們就需要對(duì)TabBar進(jìn)行自定義,在最中間空出一個(gè)TabBar的空間進(jìn)行布置這個(gè)【+】發(fā)布按鈕?!    ?/p>

我們的項(xiàng)目是仿寫(xiě)“百思不得姐”App的功能模塊進(jìn)行學(xué)習(xí)和提高,其TabBar的樣式與微博的樣式基本相似(如上圖右邊的圖),最中間的Tab按鈕也是發(fā)帖功能,也是在直接當(dāng)前的頁(yè)面上覆蓋一個(gè)編輯發(fā)布頁(yè)面,發(fā)布完成或者取消發(fā)布之后又回到之前的頁(yè)面,并沒(méi)有進(jìn)行切換。

解決方案

對(duì)于類似新浪微博和我們項(xiàng)目中這種情況有兩種解決思路:

定義5個(gè)TabBarItem,然后在TabBar上添加一個(gè)與TabBarItem等大小的發(fā)布按鈕在最中間,并添加點(diǎn)擊事件,這樣因?yàn)榇笮∠嗟龋孕掳粹o完全覆蓋了最中間的TabBarItem,最中間的TabBarItem的響應(yīng)事件也會(huì)被屏蔽,因?yàn)榘粹o會(huì)先響應(yīng)自定義TabBar,重寫(xiě)其 layoutSubviews 方法,將所有4個(gè)TabBarItem的布局和大小進(jìn)行修改,將中間空出來(lái),然后添加一個(gè)自定義的【發(fā)布】按鈕,實(shí)現(xiàn)其點(diǎn)擊事件即可 1 覆蓋控件實(shí)現(xiàn)方案

這種方案的思路在上面已經(jīng)說(shuō)到了,就是先占一個(gè)位置,然后用一個(gè)按鈕覆蓋到其上面。主要缺點(diǎn)就是需要先申請(qǐng)一個(gè)位置和控制器來(lái)占位比較浪費(fèi),而且這種也只適用于各控件的大小是均勻的情況,當(dāng)我們需求中每個(gè)TabBarItem的規(guī)格和尺寸不一樣時(shí),我們就無(wú)法使用這種方案實(shí)現(xiàn)。

有幾點(diǎn)值得說(shuō)明一下:

設(shè)置所有UITabBarItem的文字屬性在上一篇文章iOS項(xiàng)目——基本框架搭建中已經(jīng)提到了,這里就不詳細(xì)介紹了【發(fā)布】按鈕的初始化應(yīng)該使用單例模式進(jìn)行創(chuàng)建,因?yàn)槲覀冺?xiàng)目中只有一個(gè)【發(fā)布】按鈕,所以使用單例模式更合理,本文采用懶加載的方式進(jìn)行單例模式的創(chuàng)建在 viewWillAppear: 中添加【發(fā)布】按鈕 [self.tabBar addSubview:self.publishButton]; 。至于為什么要在 viewWillAppear: 中添加【發(fā)布】按鈕而不是在 viewDidLoad 中添加?根本原因就是TabBarItem加載到TabBar上是在 viewDidLoad 之后執(zhí)行的,后面在第2部分中有驗(yàn)證這一點(diǎn), 在上一文章我們就說(shuō)過(guò),tabbarcontroller是在一創(chuàng)建控制器的時(shí)候就進(jìn)行加載viewdidLoad。所以,如果添加【發(fā)布】按鈕在viewDidLoad中會(huì)造成【發(fā)布】按鈕在TabBar中是第一個(gè)添加的,這樣會(huì)導(dǎo)致【發(fā)布】按鈕會(huì)被TabBarItem覆蓋了,這樣我們就達(dá)到我們的目的。

#import "XMGTabBarController.h"

@interface XMGTabBarController ()
/** 中間的發(fā)布按鈕 */
@property (nonatomic, strong) UIButton *publishButton;

@end

@implementation XMGTabBarController

#pragma mark - 初始化
- (void)viewDidLoad {
 [super viewDidLoad];
 
 /**** 設(shè)置所有UITabBarItem的文字屬性 ****/
 UITabBarItem *item = [UITabBarItem appearance];
 // 普通狀態(tài)下的文字屬性
 NSMutableDictionary *normalAttrs = [NSMutableDictionary dictionary];
 normalAttrs[NSFontAttributeName] = [UIFont systemFontOfSize:14];
 normalAttrs[NSForegroundColorAttributeName] = [UIColor grayColor];
 [item setTitleTextAttributes:normalAttrs forState:UIControlStateNormal];
 // 選中狀態(tài)下的文字屬性
 NSMutableDictionary *selectedAttrs = [NSMutableDictionary dictionary];
 selectedAttrs[NSForegroundColorAttributeName] = [UIColor darkGrayColor];
 [item setTitleTextAttributes:normalAttrs forState:UIControlStateSelected];
 
 /**** 添加子控制器 ****/
 [self setupOneChildViewController:[[UITableViewController alloc] init] title:@"精華" image:@"tabBar_essence_icon" selectedImage:@"tabBar_essence_click_icon"];
 [self setupOneChildViewController:[[UITableViewController alloc] init] title:@"新帖" image:@"tabBar_new_icon" selectedImage:@"tabBar_new_click_icon"];
 
 // 中間用來(lái)占位的子控制器
 [self setupOneChildViewController:[[UIViewController alloc] init] title:nil image:nil selectedImage:nil];
 
 [self setupOneChildViewController:[[UIViewController alloc] init] title:@"關(guān)注" image:@"tabBar_friendTrends_icon" selectedImage:@"tabBar_friendTrends_click_icon"];
 [self setupOneChildViewController:[[UITableViewController alloc] init] title:@"我" image:@"tabBar_me_icon" selectedImage:@"tabBar_me_click_icon"];
}

/**
 * 為什么要在viewWillAppear:方法中添加發(fā)布按鈕?
 * 當(dāng)viewWillAppear:方法被調(diào)用的時(shí)候, tabBar內(nèi)部已經(jīng)添加了5個(gè)UITabBarButton
 * 就可以實(shí)現(xiàn)一個(gè)效果 : [發(fā)布按鈕]蓋在其他UITabBarButton上面
 */
- (void)viewWillAppear:(BOOL)animated
{
 [super viewWillAppear:animated];
 
 /**** 增加一個(gè)發(fā)布按鈕 ****/
 [self.tabBar addSubview:self.publishButton];
}
#pragma mark - 懶加載
/** 發(fā)布按鈕 */
- (UIButton *)publishButton
{
 if (!_publishButton) {
 _publishButton = [UIButton buttonWithType:UIButtonTypeCustom];
 _publishButton.backgroundColor = XMGRandomColor;
 [_publishButton setImage:[UIImage imageNamed:@"tabBar_publish_icon"] forState:UIControlStateNormal];
 [_publishButton setImage:[UIImage imageNamed:@"tabBar_publish_click_icon"] forState:UIControlStateHighlighted];
 _publishButton.frame = CGRectMake(0, 0, self.tabBar.frame.size.width / 5, self.tabBar.frame.size.height);
 _publishButton.center = CGPointMake(self.tabBar.frame.size.width * 0.5, self.tabBar.frame.size.height * 0.5);
 [_publishButton addTarget:self action:@selector(publishClick) forControlEvents:UIControlEventTouchUpInside];
 }
 return _publishButton;
}
#pragma mark - 監(jiān)聽(tīng)
/**
 * 發(fā)布按鈕點(diǎn)擊
 */
- (void)publishClick
{
 XMGLogFunc
 XMGTestViewController *test = [[XMGTestViewController alloc] init];
 [self presentViewController:test animated:YES completion:nil];
}
@end

 2 自定義TabBar

自定義TabBar可以完全按照我們的需求來(lái)布局和配置TabBar中各子控件的屬性和布局。

@interface XMGTabBarController ()
@end

@implementation XMGTabBarController
#pragma mark - 初始化
- (void)viewDidLoad {
 [super viewDidLoad];
 
 /**** 設(shè)置所有UITabBarItem的文字屬性 ****/
 //省略
 
 /**** 添加子控制器 ****/
 [self setupOneChildViewController:[[UITableViewController alloc] init] title:@"精華" image:@"tabBar_essence_icon" selectedImage:@"tabBar_essence_click_icon"];
 [self setupOneChildViewController:[[UITableViewController alloc] init] title:@"新帖" image:@"tabBar_new_icon" selectedImage:@"tabBar_new_click_icon"];
 [self setupOneChildViewController:[[UIViewController alloc] init] title:@"關(guān)注" image:@"tabBar_friendTrends_icon" selectedImage:@"tabBar_friendTrends_click_icon"];
 [self setupOneChildViewController:[[UITableViewController alloc] init] title:@"我" image:@"tabBar_me_icon" selectedImage:@"tabBar_me_click_icon"];
 
 /**** 更換TabBar ****/
 [self setValue:[[XMGTabBar alloc] init] forKeyPath:@"tabBar"];
}
@end

下面的代碼是我們自定義TabBar的.m文件的主要內(nèi)容,主要是重寫(xiě)其 layoutSubviews 方法,在該方法中我們是將四個(gè)按鈕的大小和布局進(jìn)行了調(diào)整,然后在最中間添加一個(gè)【發(fā)布】按鈕。同樣的,也有幾點(diǎn)需要注意的:

【發(fā)布】按鈕的初始化還是和上面一樣,應(yīng)該采用單例模式進(jìn)行初始化,具體就不展開(kāi);重寫(xiě) layoutSubviews 方法時(shí),應(yīng)該先調(diào)用其父類的此方法 [super layoutSubviews]; ,這樣可以先對(duì)TabBarItem進(jìn)行布局,然后在此布局的基礎(chǔ)上進(jìn)行布局調(diào)整。調(diào)用父類布局方法的語(yǔ)句不能放在后面,更不能省略,因?yàn)榇朔椒ǔ藢?duì)TabBarItem進(jìn)行布局之外還有很多其他的配置;通過(guò) self.subviews 來(lái)獲取當(dāng)前的子控件,我們可以先進(jìn)行打印了解當(dāng)前子控件的類型和數(shù)量,然后進(jìn)行適當(dāng)?shù)暮Y選出我們需要修改的控件進(jìn)行布局,我們一般這里采用KVC的方法進(jìn)行獲取和修改,例如上面我們修改當(dāng)前的TabBar [self setValue:[[XMGTabBar alloc] init] forKeyPath:@"tabBar"]; ,關(guān)于如何獲取屬性和成員變量可以參見(jiàn):runtime獲取屬性和成員變量

#import "XMGTabBar.h"

@interface XMGTabBar()
/** 中間的發(fā)布按鈕 */
@property (nonatomic, weak) UIButton *publishButton;
@end

@implementation XMGTabBar

#pragma mark - 懶加載
/** 發(fā)布按鈕 */
- (UIButton *)publishButton
{
 if (!_publishButton) {
 UIButton *publishButton = [UIButton buttonWithType:UIButtonTypeCustom];
 publishButton.backgroundColor = XMGRandomColor;
 [publishButton setImage:[UIImage imageNamed:@"tabBar_publish_icon"] forState:UIControlStateNormal];
 [publishButton setImage:[UIImage imageNamed:@"tabBar_publish_click_icon"] forState:UIControlStateHighlighted];
 [publishButton addTarget:self action:@selector(publishClick) forControlEvents:UIControlEventTouchUpInside];
 [self addSubview:publishButton];
 _publishButton = publishButton;
 }
 return _publishButton;
}

#pragma mark - 初始化
/**
 * 布局子控件
 */
- (void)layoutSubviews
{
 [super layoutSubviews];
 
 /**** 設(shè)置所有UITabBarButton的frame ****/
 // 按鈕的尺寸
 CGFloat buttonW = self.frame.size.width / 5;
 CGFloat buttonH = self.frame.size.height;
 CGFloat buttonY = 0;
 // 按鈕索引
 int buttonIndex = 0;
 
 for (UIView *subview in self.subviews) {
 // 過(guò)濾掉非UITabBarButton
// if (![@"UITabBarButton" isEqualToString:NSStringFromClass(subview.class)]) continue;
 if (subview.class != NSClassFromString(@"UITabBarButton")) continue;
 
 // 設(shè)置frame
 CGFloat buttonX = buttonIndex * buttonW;
 if (buttonIndex >= 2) { // 右邊的2個(gè)UITabBarButton
 buttonX += buttonW;
 }
 subview.frame = CGRectMake(buttonX, buttonY, buttonW, buttonH);
 
 // 增加索引
 buttonIndex++;
 }
 
 /**** 設(shè)置中間的發(fā)布按鈕的frame ****/
 self.publishButton.frame = CGRectMake(0, 0, buttonW, buttonH);
 self.publishButton.center = CGPointMake(self.frame.size.width * 0.5, self.frame.size.height * 0.5);
}

#pragma mark - 監(jiān)聽(tīng)
- (void)publishClick
{
 XMGLogFunc
}
@end
為了驗(yàn)證現(xiàn)在1中提到TabBar加載TabBarItem是在 viewDidLoad 之后執(zhí)行,我們?cè)谧远xTabBar時(shí)進(jìn)行斷點(diǎn)調(diào)試,發(fā)現(xiàn)確實(shí)是先運(yùn)行XMGTabBarController的 viewDidLoad方法,然后才運(yùn)行自定義TabBar的 layoutSubviews 方法。

3 添加紅點(diǎn)提示

現(xiàn)在很多App的TabBarItem在有新消息時(shí)在右上角會(huì)有一個(gè)紅點(diǎn)提示,有的甚至還會(huì)有具體數(shù)目的提醒,類似我們常用的QQ、微信、微博、頭條等都會(huì)有類似的功能,這個(gè)提示在iOS中的學(xué)名叫做badge(其實(shí)是一般都這么命名而已)。在iOS的TabBarItem是自帶該屬性和控件的,我們可以根據(jù)自己的需求進(jìn)行配置,下圖是iOS11中的配置文檔,可以對(duì)提示數(shù)量、顏色進(jìn)行自定義設(shè)置,還可以對(duì)提示文字的屬性進(jìn)行不同狀態(tài)下的配置。

據(jù)說(shuō)在iOS10之前對(duì)badge的提示顏色是不能進(jìn)行配置的,這時(shí)候如果需要,我們就只能進(jìn)行自定義TabBarItem,然后對(duì)自定義的badge進(jìn)行配置。本文就不對(duì)這一點(diǎn)進(jìn)行詳細(xì)說(shuō)明了,有需要的小伙伴可以自行求助度娘。

相關(guān)文章

  • iOS?Segment帶滑動(dòng)條切換效果

    iOS?Segment帶滑動(dòng)條切換效果

    這篇文章主要為大家詳細(xì)介紹了iOS?Segment帶滑動(dòng)條切換,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • iOS開(kāi)發(fā)xconfig和script腳本使用詳解

    iOS開(kāi)發(fā)xconfig和script腳本使用詳解

    這篇文章主要為大家介紹了iOS開(kāi)發(fā)xconfig和script腳本使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • iOS開(kāi)發(fā) 正則運(yùn)算詳細(xì)介紹

    iOS開(kāi)發(fā) 正則運(yùn)算詳細(xì)介紹

    這篇文章主要介紹了iOS開(kāi)發(fā) 正則運(yùn)算的相關(guān)資料,需要的朋友可以參考下
    2016-09-09
  • 分享一些iOS開(kāi)發(fā)實(shí)用的小技巧

    分享一些iOS開(kāi)發(fā)實(shí)用的小技巧

    這篇文章主要給大家分享了一些iOS開(kāi)發(fā)實(shí)用的小技巧,這些小技巧在大家開(kāi)發(fā)iOS的時(shí)候還是相當(dāng)實(shí)用,有需要的朋友們下面來(lái)一起看看吧。
    2016-09-09
  • iOS13原生端適配攻略(推薦)

    iOS13原生端適配攻略(推薦)

    這篇文章主要介紹了iOS13原生端適配攻略(推薦),現(xiàn)匯總一下iOS 13的各種坑,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-10-10
  • 舉例詳解iOS開(kāi)發(fā)過(guò)程中的沙盒機(jī)制與文件

    舉例詳解iOS開(kāi)發(fā)過(guò)程中的沙盒機(jī)制與文件

    這篇文章主要介紹了舉例詳解iOS開(kāi)發(fā)過(guò)程中的沙盒機(jī)制與文件,示例代碼為傳統(tǒng)的Obejective-C,需要的朋友可以參考下
    2015-09-09
  • iOS指紋登錄(TouchID)集成方案詳解

    iOS指紋登錄(TouchID)集成方案詳解

    這篇文章主要為大家詳細(xì)介紹了iOS指紋登錄TouchID的集成方案,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • IOS自適配利器Masonry使用指南

    IOS自適配利器Masonry使用指南

    如果說(shuō)自動(dòng)布局解救了多屏幕適配,那眾多三方庫(kù)的出現(xiàn)就解救了系統(tǒng)自動(dòng)布局的寫(xiě)法。Masonry就是其中一個(gè)。用法上也比較簡(jiǎn)單靈活,很大程度上替代了傳統(tǒng)的NSLayoutConstraint布局方式。下面我們就來(lái)具體探討下吧
    2016-01-01
  • 簡(jiǎn)單談?wù)凜ore Animation 動(dòng)畫(huà)效果

    簡(jiǎn)單談?wù)凜ore Animation 動(dòng)畫(huà)效果

    下面小編就為大家?guī)?lái)一篇簡(jiǎn)單談?wù)凜ore Animation 動(dòng)畫(huà)效果。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-06-06
  • iOS使用UICollectionView實(shí)現(xiàn)橫向滾動(dòng)照片效果

    iOS使用UICollectionView實(shí)現(xiàn)橫向滾動(dòng)照片效果

    這篇文章主要為大家詳細(xì)介紹了iOS使用UICollectionView實(shí)現(xiàn)橫向滾動(dòng)照片效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-05-05

最新評(píng)論