先上一張效果圖:
lALPACOG82h0uBDNCKDNBNo_1242_2208.png_620x10000q90g.jpg
下面開(kāi)始說(shuō)一下思路:
第一步;先對(duì)UIView進(jìn)行擴(kuò)展,方便我們獲取它子類的一下屬性娃闲。代碼如下
#import <UIKit/UIKit.h>
@interface UIView (Extension)
@property (nonatomic,assign) CGFloat x;
@property (nonatomic,assign) CGFloat y;
@property (nonatomic,assign) CGFloat width;
@property (nonatomic,assign) CGFloat height;
@property (nonatomic,assign) CGFloat centerX;
@property (nonatomic,assign) CGFloat centerY;
@property (nonatomic,assign) CGSize size;
@end
#import "UIView+Extension.h"
@implementation UIView (Extension)
#pragma mark 重寫(xiě)set get 方法
#pragma mark x
- (void)setX:(CGFloat)x
{
CGRect frame = self.frame;
frame.origin.x = x;
self.frame = frame;
}
- (CGFloat)x
{
return self.frame.origin.x;
}
#pragma mark y
- (void)setY:(CGFloat)y
{
CGRect frame = self.frame;
frame.origin.y = y;
self.frame = frame;
}
- (CGFloat)y
{
return self.frame.origin.y;
}
#pragma mark width
- (void)setWidth:(CGFloat)width
{
CGRect frame = self.frame;
frame.size.width = width;
self.frame = frame;
}
- (CGFloat)width
{
return self.frame.size.width;
}
#pragma mark height
- (void)setHeight:(CGFloat)height
{
CGRect frame = self.frame;
frame.size.height = height;
}
- (CGFloat)height
{
return self.frame.size.height;
}
#pragma mark centerX
- (void)setCenterX:(CGFloat)centerX
{
CGPoint center = self.center;
center.x = centerX;
self.center = center;
}
- (CGFloat)centerX
{
return self.center.x;
}
#pragma mark centerY
- (void)setCenterY:(CGFloat)centerY
{
CGPoint center = self.center;
center.y = centerY;
self.center = center;
}
- (CGFloat)centerY
{
return self.center.y;
}
#pragma mark size
- (void)setSize:(CGSize)size
{
CGRect frame = self.frame;
frame.size = size;
self.frame = frame;
}
- (CGSize)size
{
return self.frame.size;
}
@end
第二步忱详,新建一個(gè)類ZLTabbar
围来,繼承自UITabBar
1、.h文件
#import <UIKit/UIKit.h>
typedef void(^IrrBtnSelectedBlock)();
@interface ZLTabbar : UITabBar
//用于監(jiān)聽(tīng)自定義tabbarButton的點(diǎn)擊事件
@property (nonatomic,copy) IrrBtnSelectedBlock selectedIrrBtn;
- (void)didselectedIrrBtnWithBlock:(IrrBtnSelectedBlock)selectedIrrBtn;
@end
這里解釋一下匈睁,我習(xí)慣用block监透,所以這里聲明了一個(gè)block類型。你也可以根據(jù)個(gè)人習(xí)慣航唆,來(lái)使用觀察者或者代理胀蛮。
2、.m文件
#import "ZLTabbar.h"
#import "UIView+Extension.h"
@interface ZLTabbar ()
@property (nonatomic,strong) UIButton *irregularItem;//不規(guī)則的按鈕糯钙,可以放在在中間或者其它任意一個(gè)地方
@end
@implementation ZLTabbar
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
//TODO:加載子視圖
[self createChildrenViews];
}
return self;
}
#pragma mark 創(chuàng)建子視圖
- (void)createChildrenViews
{
self.backgroundColor = [UIColor whiteColor];
//TODO:去掉tabbar的分割線
[self setBackgroundImage:[UIImage new]];
[self setShadowImage:[UIImage new]];
self.irregularItem = [UIButton buttonWithType:UIButtonTypeCustom];
[self.irregularItem setBackgroundImage:[UIImage imageNamed:@"midBtn"] forState:UIControlStateNormal];
[self.irregularItem setBackgroundImage:[UIImage imageNamed:@"midBtn"] forState:UIControlStateHighlighted];
self.irregularItem.size = self.irregularItem.currentBackgroundImage.size;
self.irregularItem.layer.masksToBounds = YES;
self.irregularItem.layer.cornerRadius = self.irregularItem.width/2;
[self.irregularItem addTarget:self action:@selector(irregularItemSelcted) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:self.irregularItem];
}
#pragma mark 執(zhí)行和監(jiān)聽(tīng)不規(guī)則按鈕的點(diǎn)擊事件
- (void)irregularItemSelcted
{
if (self.selectedIrrBtn)
{
self.selectedIrrBtn();
}
}
- (void)didselectedIrrBtnWithBlock:(IrrBtnSelectedBlock)selectedIrrBtn
{
self.selectedIrrBtn = selectedIrrBtn;
}
#pragma mark layoutSubviews
- (void)layoutSubviews
{
[super layoutSubviews];
//TODO:重新排布系統(tǒng)按鈕的位置粪狼,空出需要自定義按鈕的位置,系統(tǒng)按鈕的類型是UITabBarButton
Class class = NSClassFromString(@"UITabBarButton");
//TODO:這里設(shè)置自定義tabbarButton的位置
self.irregularItem.centerX = (self.width * 0.75 + self.irregularItem.width * 0.75);
self.irregularItem.centerY = self.height - self.irregularItem.height/2;
NSInteger btnIndex = 0;
for (UIView *btn in self.subviews)
{
if ([btn isKindOfClass:class])
{
//TODO:如果是系統(tǒng)的UITabBarButton超营,調(diào)整子控件位置鸳玩,空出自定義UITabBarButton的位置
//TODO:按鈕寬度為T(mén)abbar寬度平分4塊
btn.width = self.width/4;
if (btnIndex < 3)
{
//TODO: -3- 在這里為irregularItem的索引值
btn.x = btn.width * btnIndex;
}
else
{
btn.x = btn.width * btnIndex + self.irregularItem.width;
}
btnIndex ++;
if (btnIndex == 0)
{
btnIndex ++;
}
}
}
[self bringSubviewToFront:self.irregularItem];
}
#pragma mark 重寫(xiě)hitTest方法,去監(jiān)聽(tīng)irregularItem的點(diǎn)擊演闭,目的是為了讓突出在外面的部分 在點(diǎn)擊時(shí)也有反應(yīng)
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
/**判斷當(dāng)前手指是否點(diǎn)擊到了irregularItem不跟。如果是,則相應(yīng)按鈕點(diǎn)擊米碰;如果是其它窝革,則由系統(tǒng)處理**/
//當(dāng)前view是否被隱藏?如果隱藏吕座,就不做其他處理了虐译。
if (self.isHidden == NO)
{
//TODO:將當(dāng)前tabbar的觸摸點(diǎn)轉(zhuǎn)換成坐標(biāo)系,轉(zhuǎn)換到irregularItem的身上吴趴,生成一個(gè)新的點(diǎn)
CGPoint new_point = [self convertPoint:point toView:self.irregularItem];
//TODO:如果這個(gè)新的點(diǎn)是在irregularItem上漆诽,那么處理點(diǎn)點(diǎn)擊事件最合適的view就是irregularItem
if ([self.irregularItem pointInside:new_point withEvent:event])
{
return self.irregularItem;
}
}
return [super hitTest:point withEvent:event];
}
@end
說(shuō)明:
1.在
layoutSubviews
方法中,重設(shè)自定義以及系統(tǒng)的tabbarButton的位置。
2.如果不重寫(xiě)hitTest
方法厢拭,點(diǎn)擊突出在外面的button
會(huì)無(wú)事件響應(yīng)兰英。
3.當(dāng)調(diào)整自定義tabbarButton
的位置時(shí),還有可能需要調(diào)整它的索引值供鸠。此時(shí)畦贸,它的索引值為3
;
第三步楞捂,創(chuàng)建tabbarController
.m文件
#import "ZLTabbarController.h"
#import "LeftViewController.h"
#import "RightViewController.h"
#import "MidViewController.h"
#import "ResourceViewController.h"
#import "ZLTabbar.h"
@interface ZLTabbarController ()
@end
@implementation ZLTabbarController
- (void)viewDidLoad {
[super viewDidLoad];
[self setupTabbar];
}
#pragma mark 設(shè)置tabbar
- (void)setupTabbar
{
LeftViewController *left = [[LeftViewController alloc]init];
[self createChildrenVC:left
childrenVCTitle:@"首頁(yè)"
image:[UIImage imageNamed:@"首頁(yè)"]
selectedImage:[UIImage imageNamed:@"首頁(yè)_S"]];
ResourceViewController *resource = [[ResourceViewController alloc]init];
[self createChildrenVC:resource
childrenVCTitle:@"資源"
image:[UIImage imageNamed:@"資源"]
selectedImage:[UIImage imageNamed:@"資源_S"]];
RightViewController *right = [[RightViewController alloc]init];
[self createChildrenVC:right
childrenVCTitle:@"個(gè)人中心"
image:[UIImage imageNamed:@"個(gè)人中心"]
selectedImage:[UIImage imageNamed:@"個(gè)人中心_S"]];
ZLTabbar *tabbar = [[ZLTabbar alloc]init];
tabbar.selectedItem = left.tabBarItem;
MidViewController *mid = [[MidViewController alloc]init];
[tabbar didselectedIrrBtnWithBlock:^{
[self presentViewController:mid animated:YES completion:nil];
}];
[self setValue:tabbar forKey:@"tabBar"];
}
#pragma mark 添加子控制器
- (void)createChildrenVC:(UIViewController *)childViewController
childrenVCTitle:(NSString *)title
image:(UIImage *)image
selectedImage:(UIImage *)selectedImg
{
//設(shè)置選中時(shí)item的字體顏色
UIColor *selectedTinColor = [UIColor colorWithRed:60.0/255
green:160.0/255
blue:220.0/255
alpha:1.0f];
[[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObject:NSForegroundColorAttributeName
forKey:selectedTinColor]
forState:UIControlStateSelected];
//設(shè)置未選中的image
UIImage *deselectedImage = image;
deselectedImage = [deselectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
childViewController.tabBarItem.image = deselectedImage;
//設(shè)置選中的image
UIImage *selectedImage = selectedImg;
selectedImage = [selectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
childViewController.tabBarItem.selectedImage = selectedImage;
//設(shè)置tabbarItem文字和圖標(biāo) 之間的距離
childViewController.tabBarItem.title = title;
// childViewController.tabBarItem.titlePositionAdjustment = UIOffsetMake(0, MAXFLOAT);
//添加控制器對(duì)象
UINavigationController *childNavigationContorller = [[UINavigationController alloc]initWithRootViewController:childViewController];
[self addChildViewController:childNavigationContorller];
}
@end
說(shuō)明:
1.我們可通過(guò)
tabBarItem.titlePositionAdjustment
來(lái)設(shè)置文字與圖表之間的距離薄坏,當(dāng)值為MAXFLOAT
時(shí),這個(gè)方法也起到了隱藏文字的作用寨闹。當(dāng)然胶坠,你可以直接tabBarItem.title
設(shè)置為空字符串對(duì)象。
2.我們可以通過(guò)[tabbar didselectedIrrBtnWithBlock:^{ /**在這里做一些操作**/ }];
來(lái)響應(yīng)一些操作繁堡。