屏幕快照 2019-04-29 上午9.36.53.png
我們?cè)趯憈abbar時(shí),有時(shí)會(huì)出現(xiàn)如上圖的要求,中間的item要突出來.
我們要想實(shí)現(xiàn)這個(gè)需求只需要自定義一個(gè)中間突出的item.其余的幾個(gè)就可以完全使用系統(tǒng)創(chuàng)建就可以.
1.首先創(chuàng)建一個(gè)ApplyTabBar繼承自UITabBar
ApplyTabBar.h
#import <UIKit/UIKit.h>
@class ApplyTabBar;
@protocol ApplyTabBarDelegate <NSObject>
@optional
/** 點(diǎn)擊按鈕回調(diào)方法 */
- (void)tabBarPlusBtnClick:(ApplyTabBar *)tabBar;
@end
@interface ApplyTabBar : UITabBar
/** tabbar的協(xié)議方法 */
@property (nonatomic, weak) id<ApplyTabBarDelegate> myDelegate ;
@end
ApplyTabBar.m
#import "ApplyTabBar.h"
@interface ApplyTabBar ()
/** plus按鈕 */
@property (nonatomic, weak) UIButton *plusBtn ;
@property UILabel *titleLabel;
@end
@implementation ApplyTabBar
- (instancetype)initWithFrame:(CGRect)frame{
if (self=[super initWithFrame:frame]) {
self.backgroundColor = [UIColor whiteColor];
UIButton *plusBtn = [[UIButton alloc] init];
[plusBtn setBackgroundImage:[UIImage imageNamed:@"applyImage"] forState:UIControlStateNormal];
[plusBtn setBackgroundImage:[UIImage imageNamed:@"applyImage"] forState:UIControlStateHighlighted];
self.plusBtn = plusBtn;
[plusBtn addTarget:self action:@selector(plusBtnDidClick) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:plusBtn];
self.titleLabel = [[UILabel alloc] init];
self.titleLabel.text = @"申領(lǐng)";
self.titleLabel.textAlignment = NSTextAlignmentCenter;
self.titleLabel.font = [UIFont systemFontOfSize:11];
[self.titleLabel sizeToFit];
self.titleLabel.textColor = [UIColor grayColor];
[self addSubview:self.titleLabel];
}
return self;
}
- (void)layoutSubviews{
[super layoutSubviews];
//系統(tǒng)自帶的按鈕類型是UITabBarButton圣勒,找出這些類型的按鈕饵史,然后重新排布位置阅虫,空出中間的位置
Class class = NSClassFromString(@"UITabBarButton");
int btnIndex = 0;
CGFloat btnHeight = 0;
for (UIView *btn in self.subviews) {//遍歷tabbar的子控件
if ([btn isKindOfClass:class]) {//如果是系統(tǒng)的UITabBarButton厦幅,那么就調(diào)整子控件位置矮慕,空出中間位置
//每一個(gè)按鈕的寬度==tabbar的五分之一(因?yàn)槲疫@里一共五個(gè)item)
btn.frame = CGRectMake(self.frame.size.width / 5 * btnIndex, btn.frame.origin.y, self.frame.size.width / 5, btn.frame.size.height);
btnHeight = btn.frame.origin.y;
btnIndex++;
//如果是索引是2(從0開始的)填物,直接讓索引++毛萌,目的就是讓消息按鈕的位置向右移動(dòng)损晤,空出來發(fā)布按鈕的位置
if (btnIndex == 2) {
btnIndex++;
}
}
}
self.plusBtn.center = CGPointMake(self.center.x, self.plusBtn.center.y);
//調(diào)整發(fā)布按鈕的中線點(diǎn)Y值
self.titleLabel.center = CGPointMake(self.plusBtn.center.x, btnHeight+ 47-self.titleLabel.frame.size.height/2);
self.plusBtn.center = CGPointMake(self.plusBtn.center.x, 5);
self.plusBtn.frame = CGRectMake(self.plusBtn.frame.origin.x, self.plusBtn.frame.origin.y, self.titleLabel.frame.origin.y*2-5, self.titleLabel.frame.origin.y*2-5);
[self bringSubviewToFront:self.plusBtn];
}
//點(diǎn)擊了發(fā)布按鈕
- (void)plusBtnDidClick{
//如果tabbar的代理實(shí)現(xiàn)了對(duì)應(yīng)的代理方法脆粥,那么就調(diào)用代理的該方法
if ([self.delegate respondsToSelector:@selector(tabBarPlusBtnClick:)]) {
[self.myDelegate tabBarPlusBtnClick:self];
}
}
@end
無論你使用storyboard還是代碼設(shè)置tabbar 我們都需要自定義一個(gè)UITabBarController.用來關(guān)聯(lián)storyboard中UITabBarController或者直接使用自定義UITabBarController來添加中間的突出item
這里一stroyboard為例
1.storyboard創(chuàng)建UITabBarController并添加四個(gè)item
屏幕快照 2019-04-29 上午10.15.30.png
2.關(guān)聯(lián)自定義UITabBarController
3.在viewdidload方法中添加代碼
ApplyTabBar *tabbar = [[ApplyTabBar alloc] init];
tabbar.myDelegate = self;
[self setValue:tabbar forKeyPath:@"tabBar"];
到這我們就可以運(yùn)行程序中間的突出item就出來了
后來發(fā)現(xiàn)一個(gè)問題,當(dāng)我們點(diǎn)擊中間突出item超出tabbar高度的地方發(fā)現(xiàn)不會(huì)觸發(fā)我們的點(diǎn)擊方法.
在這我們需要在ApplyTabBar.m中重寫- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event方法
//重寫hitTest方法砌溺,去監(jiān)聽發(fā)布按鈕的點(diǎn)擊,目的是為了讓凸出的部分點(diǎn)擊也有反應(yīng)
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
//我們只需要在tabbar未隱藏時(shí)重寫當(dāng)前方法
if (self.isHidden == NO) {
//將當(dāng)前tabbar的觸摸點(diǎn)轉(zhuǎn)換坐標(biāo)系变隔,轉(zhuǎn)換到發(fā)布按鈕的身上规伐,生成一個(gè)新的點(diǎn)
CGPoint newP = [self convertPoint:point toView:self.plusBtn];
//判斷是否在添加按鈕上
if ( [self.plusBtn pointInside:newP withEvent:event]) {
return self.plusBtn;
}else{
return [super hitTest:point withEvent:event];
}
}else {
return [super hitTest:point withEvent:event];
}
}