工作中,系統(tǒng)的TabBar往往無法滿足我們的需求,下面就分享一下兩種自定義TabBar的類型.
- 第一種tabBarItem為純圖片;
![Uploading 屏幕快照 2015-12-30 下午9.29.06_173366.png . . .]
- 第二種非主流型的,中間需要自定義的
針對第一種,系統(tǒng)的TabBar有一個image和tilte,如果使用系統(tǒng)的TabBar會顯得非常難看
所以我們需要自定義TabBar
新建一個類繼承UIView
.h文件
#import <UIKit/UIKit.h>
@class XJTabBar;
@protocol XJTabBarDelegate <NSObject>
@optional
//tabBarItem的點擊,將索引傳出去
- (void)tabBar:(XJTabBar *)tabBar didClickbtn:(NSInteger)index;
@end
@interface XJTabBar : UIView
/** 子控件個數(shù)由外面的控制器決定 */
@property (nonatomic, strong) NSArray *items;
@property (nonatomic, weak) id<XJTabBarDelegate> delegate;
.m文件
@implementation XJTabBar
- (void)setItems:(NSArray *)items
{
_items = items;
for (int i = 0; i < items.count; i++) {
UITabBarItem *item = items[i];
XJTabBarBtn *btn = [[XJTabBarBtn alloc] init];
[btn setBackgroundImage:item.image forState:UIControlStateNormal];
[btn setBackgroundImage:item.selectedImage forState:UIControlStateSelected];
btn.tag = i;
[btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchDown];
if (i == 0) {
[self btnClick:btn];
}
[self addSubview:btn];
}
}
- (void)layoutSubviews
{
[super layoutSubviews];
CGFloat btnW = self.bounds.size.width / _items.count;
CGFloat btnH = self.bounds.size.height;
CGFloat btnX = 0;
CGFloat btnY = 0;
for (int i = 0; i < _items.count; i++) {
XJTabBarBtn *btn = self.subviews[i];
btnX = i * btnW;
btn.frame = CGRectMake(btnX, btnY, btnW, btnH);
}
}
以上自定義TabBar就基本完成了,現(xiàn)在只需要在控制器中使用就OK了
自定義UITabBarController中
//初始化自定義tabBar
- (void)setuptabBar
{ //先將系統(tǒng)tabBar 移除
// [self.tabBar removeFromSuperview];
// 這里為什么我注銷了呢? 因為是自定義的UITabBar,在push的時候,如果想要通過 `hidesBottomBarWhenPushed` 方法隱藏tabBar是無法實現(xiàn)的
XJTabBar *tabBar = [[XJTabBar alloc] init];
tabBar.frame = self.tabBar.bounds;
tabBar.items = self.tabBarArr;
tabBar.delegate = self;
[self.tabBar addSubview:tabBar];
}
現(xiàn)在基本上就是這個樣子(下面的文字是由于我設置了控制器的title)
但是由于系統(tǒng)的UITabBarButton,尺寸還是顯示不正確,所以需要將它刪除掉,遍歷tabbar的所有子控件,但是UITabBarButton是私有變量無法直接刪除,如下,將不是自定義的XJTabBar的子控件刪除
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
for (UIView *childView in self.tabBar.subviews) {
if ([childView isKindOfClass:[XJTabBar class]] == NO) {
[childView removeFromSuperview];
}
}
}
最后的結果(點擊的時候按鈕有高亮狀態(tài),自定義button,重寫setHighlighted)
- (void)setHighlighted:(BOOL)highlighted
{
}
因為是自定義的UITabBar是繼承UIView的,無法像系統(tǒng)的那樣響應點擊事件,切換控制器,所以需要實現(xiàn)代理方法
#pragma mark <tabBar代理方法>
- (void)tabBar:(XJTabBar *)tabBar didClickbtn:(NSInteger)index
{
//selectedindex是系統(tǒng)自帶的屬性,只要將按鈕的索引傳給它,就能實現(xiàn)點擊切換控制器了
self.selectedIndex = index;
}
第二種UITabBar是百思不得姐的,中間的加號點擊需要modal出一個控制器,所以系統(tǒng)的也無法滿足我們的需求
實現(xiàn)思路和第一中有一點區(qū)別,這個我是直接繼承系統(tǒng)的UITabBar,在上面做一些改變
.h文件
#import <UIKit/UIKit.h>
@class XJTabBar;
@protocol XJTabBarDelegate <NSObject>
@optional
//加號按鈕的點擊
- (void)tabBarDidPulsBtnClick:(XJTabBar *)tabBar;
@end
@interface XJTabBar : UITabBar
/**代理 */
@property (nonatomic, weak) id<XJTabBarDelegate> delegate;
@end
.m文件
#import "XJTabBar.h"
@interface XJTabBar ()
/** 加號按鈕 */
@property (nonatomic, weak) UIButton *pulsBtn;
@end
@implementation XJTabBar
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
//添加中間加號按鈕
UIButton *pulsBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[pulsBtn setBackgroundImage:[UIImage imageNamed:@"tabBar_publish_icon"] forState:UIControlStateNormal];
[pulsBtn setBackgroundImage:[UIImage imageNamed:@"tabBar_publish_click_icon"] forState:UIControlStateHighlighted];
[pulsBtn sizeToFit];
self.pulsBtn = pulsBtn;
[self addSubview:pulsBtn];
[pulsBtn addTarget:self action:@selector(pulsBtnClick) forControlEvents:UIControlEventTouchUpInside];
}
return self;
}
- (void)layoutSubviews
{
[super layoutSubviews];
NSInteger count = self.items.count + 1;
CGFloat w = self.bounds.size.width / count;
CGFloat h = self.bounds.size.height;
CGFloat x = 0;
CGFloat y = 0;
int i = 0;
for(UIView *btn in self.subviews) {
if ([btn isKindOfClass:NSClassFromString(@"UITabBarButton")]) {
if (i == 2) {
i += 1;
}
x = i * w;
btn.frame = CGRectMake(x, y, w, h);
i++;
}
//設置加號按鈕尺寸
self.pulsBtn.center = CGPointMake(self.bounds.size.width * 0.5, self.bounds.size.height * 0.5);
}
}
- (void)pulsBtnClick
{
if ([self.delegate respondsToSelector:@selector(tabBarDidPulsBtnClick:)]) {
[self.delegate tabBarDidPulsBtnClick:self];
}
}
@end
在自定義的UITabBarController中,將系統(tǒng)的UITabBar替換掉就OK了
- (void)viewDidLoad
{
[super viewDidLoad];
//@property(nonatomic,readonly) UITabBar *tabBar
//tabbar是readonly的,所以只能通過KVC賦值,不能直接更改
//為什么在這里更改系統(tǒng)的tabBar,在這里系統(tǒng)的tabBar還沒有值
XJTabBar *tabBar = [[XJTabBar alloc] init];
tabBar.delegate = self;
[self setValue:tabBar forKeyPath:@"tabBar"];
}
最后實現(xiàn)加號對應的代理方法就行了,就能實現(xiàn)上圖的效果了!
以上就是我對自定義tabBar的簡單使用了,請多指教.......!
qq:1243157398