本章知識點梳理
- 1.設(shè)置UITabBarItem 圖片不渲染
- 2.自定義tabBar 與 不自定義tabBar 多種方式實現(xiàn)
- 3.tabBar主題
- 4.自定義UITabBarController,添加所有子控制器
1 赴涵、設(shè)置UITabBarItem 圖片不渲染
-
代碼實現(xiàn)
Snip20150901_5.png -
系統(tǒng)設(shè)置實現(xiàn)
Snip20150901_6.png
2媒怯、自定義tabbar
Snip20151026_14.png
2.1 思路分析
需求:點擊中間按鈕订讼,modal方式彈出一個控制器
-
方案一:
- 設(shè)置UITabController設(shè)置5個子控制器髓窜,然后將 中間按鈕添加到UITabBar 中間
- 方案:不佳,因為這樣可能按鈕會先添加欺殿,而被UITabBar蓋著了寄纵,監(jiān)聽不到按鈕事件,我們想讓按鈕后添加(UITabBar添加后:ViewWillAppear方法中),但是還是太麻煩脖苏,你設(shè)置了5個控制器這樣浪費一個控制器程拭。
- 設(shè)置UITabController設(shè)置5個子控制器髓窜,然后將 中間按鈕添加到UITabBar 中間
-
方案二:丟棄系統(tǒng)自帶的UITabBar,而使用我們自定義的UITabBar棍潘,繼承UITabBar恃鞋,
使用KVC替換
- 注意:
- 中間“加號按鈕”,采用UIButton亦歉,而不能采用UITabBarButton
- 按照現(xiàn)在的需求恤浪,我們不能使用 UITabBarButton,而選擇使用UIButton肴楷,因為TabBar的UITabBarButton只能有一個選中水由,其他將取消選中,但是我們想實現(xiàn)赛蔫,點擊“加號”不影響UITabBarButton的選中狀態(tài)砂客,而且UITabBarButton是上圖下文字泥张,不符合我們現(xiàn)在的需求。
- 系統(tǒng)自帶的tabBar是只讀的鞠值,不能直接賦值媚创,KVC方式替換只有
-
UITabBarButton系統(tǒng)是不對我們開放的,通過以下兩種方式彤恶,我們可以判斷是否是UITabBarButton類型
![Snip20150901_27.png](http://upload-images.jianshu.io/upload_images/831339-1c873b9398247534.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- 中間“加號按鈕”,采用UIButton亦歉,而不能采用UITabBarButton
- 步驟:
- 在自定義的UITabBarController中筝野,使用KVC,進(jìn)行設(shè)置替換系統(tǒng)自帶的TabBar粤剧,
- 然后我們就可以自定義的TabBar的initWithFrame:方法中添加中間“加號按鈕”歇竟,
- 重寫LayoutSubViews方法布局子控件=》布局UITabBarButton(TabBar每一項)、加號按鈕抵恋。
- 注意:
// 1. 在自定義UITabBarController控制器中焕议,KVC方式替換系統(tǒng)TabBar
- (void)viewDidLoad {
[super viewDidLoad];
self setValue:[[JPTabBar alloc] init] forKeyPath:@"tabBar"];
// 2. 自定義TabBar
#import "JPTabBar.h"
#import "JPPublishViewController.h"
@interface JPTabBar()
/** 發(fā)布按鈕 */
@property (nonatomic, weak) UIButton *publishButton;
@end
@implementation JPTabBar
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
// 設(shè)置背景圖片
self.backgroundImage = [UIImage imageNamed:@"tabbar-light"];
// 添加發(fā)布按鈕
UIButton *publishButton = [UIButton buttonWithType:UIButtonTypeCustom];
[publishButton setBackgroundImage:[UIImage imageNamed:@"tabBar_publish_icon"] forState:UIControlStateNormal];
[publishButton setBackgroundImage:[UIImage imageNamed:@"tabBar_publish_click_icon"] forState:UIControlStateHighlighted];
[publishButton sizeToFit];
[publishButton addTarget:self action:@selector(publishClick) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:publishButton];
self.publishButton = publishButton;
}
return self;
}
- (void)publishClick
{
JPPublishViewController *publish = [[JPPublishViewController alloc] init];
[self.window.rootViewController presentViewController:publish animated:NO completion:nil];
}
/**
* 布局子控件
*/
- (void)layoutSubviews
{
[super layoutSubviews];
// tabBar的尺寸
CGFloat width = self.width;
CGFloat height = self.height;
// 設(shè)置發(fā)布按鈕的位置
self.publishButton.center = CGPointMake(width * 0.5, height * 0.5);
// 按鈕索引
int index = 0;
// 按鈕的尺寸
CGFloat tabBarButtonW = width / 5;
CGFloat tabBarButtonH = height;
CGFloat tabBarButtonY = 0;
// 設(shè)置4個TabBarButton的frame
for (UIView *tabBarButton in self.subviews) {
if (![NSStringFromClass(tabBarButton.class) isEqualToString:@"UITabBarButton"]) continue;
// 計算按鈕的X值
CGFloat tabBarButtonX = index * tabBarButtonW;
if (index >= 2) { // 給后面2個button增加一個寬度的X值
tabBarButtonX += tabBarButtonW;
}
// 設(shè)置按鈕的frame
tabBarButton.frame = CGRectMake(tabBarButtonX, tabBarButtonY, tabBarButtonW, tabBarButtonH);
// 增加索引
index++;
}
}
@end
- 方案三
- 完全自定義,創(chuàng)建一個類繼承UIView弧关,里面添加5個按鈕盅安,然后布局按鈕位置,然后顯示在系統(tǒng)的tabbar的上面世囊,覆蓋在上面别瞭,因為系統(tǒng)的沒有了,直接將其移除即可株憾。
- 至于如何監(jiān)聽按鈕點擊蝙寨,我們可以給按鈕綁定tag值,然后點擊按鈕事件就可以通過按鈕的tag來確定點擊了第幾個按鈕->來切換對應(yīng)的控制器嗤瞎。
- 當(dāng)然切換控制器還要拿到tabBarController墙歪,是的,也有多種方式
- 方式一:在tabBarController控制器中贝奇,做對應(yīng)的切換子控制器操作
- 我們可以定義協(xié)議虹菲,讓后讓tabBarController遵守協(xié)議,成為自定義類的代理掉瞳,然后在自定義的按鈕點擊事件將點擊的按鈕的tag值毕源,傳過來,-> 有索引陕习,有tabBarController(有selectedViewController屬性好像)霎褐,就可以做對應(yīng)的切換操作了.
- 方式二:在自定義View類中,做對應(yīng)的切換tabBarController子控制器操作
- 在按鈕點擊事件中衡查,我們?nèi)〉昧税粹o的tag瘩欺,也就是切換子控制器的索引,所以現(xiàn)在我們 拿到tabBarController就可以切換子控制器了,其實很簡單俱饿,如果讓tabBarController成為了主窗口的根控制器歌粥,所以我們拿到主窗口的根控制器,不就是tabBarController拍埠,有要切換子控制器的索引失驶,有tabBarController,就可以做切換操作了
- 方式一:在tabBarController控制器中贝奇,做對應(yīng)的切換子控制器操作
3枣购、設(shè)置tabBar主題
- 統(tǒng)一給所有的UITabBarItem設(shè)置文字屬性嬉探,默認(rèn)與選中樣式
/**
* 設(shè)置item屬性
*/
- (void)setupItem
{
// UIControlStateNormal狀態(tài)下的文字屬性
NSMutableDictionary *normalAttrs = [NSMutableDictionary dictionary];
// 文字顏色
normalAttrs[NSForegroundColorAttributeName] = [UIColor grayColor];
// 文字大小
normalAttrs[NSFontAttributeName] = [UIFont systemFontOfSize:12];
// UIControlStateSelected狀態(tài)下的文字屬性
NSMutableDictionary *selectedAttrs = [NSMutableDictionary dictionary];
// 文字顏色
selectedAttrs[NSForegroundColorAttributeName] = [UIColor darkGrayColor];
// 統(tǒng)一給所有的UITabBarItem設(shè)置文字屬性
// 只有后面帶有UI_APPEARANCE_SELECTOR的屬性或方法, 才可以通過appearance對象來統(tǒng)一設(shè)置
UITabBarItem *item = [UITabBarItem appearance];
[item setTitleTextAttributes:normalAttrs forState:UIControlStateNormal];
[item setTitleTextAttributes:selectedAttrs forState:UIControlStateSelected];
}
4、自定義UITabBarController
- 添加所有的子控制器
@implementation JPTabBarController
- (void)viewDidLoad {
[super viewDidLoad];
// 設(shè)置item屬性
[self setupItem];
// 添加所有的子控制器
[self setupChildVcs];
// 處理TabBar棉圈,KVC替換為自定義tabBar
self setValue:[[JPTabBar alloc] init] forKeyPath:@"tabBar"];
}
/**
* 添加所有的子控制器
*/
- (void)setupChildVcs
{
[self setupChildVc:[[UIViewController alloc] init] title:@"關(guān)注" image:@"tabBar_friendTrends_icon" selectedImage:@"tabBar_friendTrends_click_icon"];
[self setupChildVc:[[UIViewController alloc] init] title:@"首頁" image:@"tabBar_essence_icon" selectedImage:@"tabBar_essence_click_icon"];
[self setupChildVc:[[UIViewController alloc] init] title:@"發(fā)現(xiàn)" image:@"tabBar_new_icon" selectedImage:@"tabBar_new_click_icon"];
[self setupChildVc:[[UIViewController alloc] initWithStyle:UITableViewStyleGrouped] title:@"我" image:@"tabBar_me_icon" selectedImage:@"tabBar_me_click_icon"];
}
/**
* 添加一個子控制器
* @param title 文字
* @param image 圖片
* @param selectedImage 選中時的圖片
*/
- (void)setupChildVc:(UIViewController *)vc title:(NSString *)title image:(NSString *)image selectedImage:(NSString *)selectedImage
{
// 包裝一個導(dǎo)航控制器
JPNavigationController *nav = [[JPNavigationController alloc] initWithRootViewController:vc];
[self addChildViewController:nav];
// 設(shè)置子控制器的tabBarItem
nav.tabBarItem.title = title;
nav.tabBarItem.image = [UIImage imageNamed:image];
nav.tabBarItem.selectedImage = [UIImage imageNamed:selectedImage];
}
@end