·>本文原创,在此记录一下自定义TabBar的几种方式,有适用于微博
、QQ空间
之类的简单方法;也有适用喜马拉雅
,闲鱼
,转转
之类的稍复杂的方法。
1、设置tabBarItem的图片渲染模式
该方式,按钮超出tabBar范围的部分不能响应点击
@implementation CustomTabBarController
- (void)viewDidLoad {
[super viewDidLoad];
self.delegate = self;
// 设置中间item的image样式,并设置其渲染模式为原始状态(不使用tint color)
UITabBarItem *item = [self.tabBar.items objectAtIndex:1];
item.image = IMG(@"add_icon") imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
// 设置item图片的位置达到满足我们需求
[item setImageInsets:UIEdgeInsetsMake(3, 0, -3, 0)];
}
#pragma mark - UITabBarControllerDelegate
// 拦截中间item的点击事件
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {
return YES;
}
end
2、创建一个按钮直接添加到系统的tabBar上
该方式,按钮超出tabBar范围的部分不能响应点击
@implementation CustomTabBarController
- (void)viewDidLoad {
UIButton* button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 136, 53)];
button.center = CGPointMake(kSCREEN_W/2, 22);
[button setBackgroundImage:IMG(@"add_icon") forState:UIControlStateNormal];
[button addTarget:self action:@selector(addAction) forControlEvents:UIControlEventTouchUpInside];
[self.tabBar addSubview:button];
}
- (void)addAction {
NSLog(@"点击了");
}
end
3、使用KVC替换系统的tabbar
使用该方式,按钮超出tabBar范围的部分可以响应点击
################# CustomTabBarController
@implementation CustomTabBarController
- (void)viewDidLoad {
[self configureChildVC];
CustomTabBar *tabbar = [[CustomTabBar alloc] init];
[tabbar setCenterBtnSize:CGSizeMake(136, 53) center:CGPointMake(kSCREEN_W/2, 22) image:IMG(@"add_icon")];
tabbar.centerClick = ^{
NSLog(@"点击了");
};
[self setValue:tabbar forKey:@"tabBar"];
}
end
################# CustomTabBar
#import <UIKit/UIKit.h>
@interface CustomTabBar : UITabBar
@property (nonatomic, copy) void(^centerClick)(void);
- (void)setCenterBtnSize:(CGSize)size center:(CGPoint)center image:(UIImage *)image;
@end
#import "CustomTabBar.h"
#import "UIView+HKExtension.h"
@interface CustomTabBar ()
/** 中间按钮 */
@property (nonatomic, weak) UIButton *centerBtn;
@end
@implementation CustomTabBar
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
UIButton *centerBtn = [[UIButton alloc] init];
[centerBtn addTarget:self action:@selector(centerBtnDidClick) forControlEvents:UIControlEventTouchUpInside];
self.centerBtn = centerBtn;
[self addSubview:centerBtn];
}
return self;
}
- (void)setCenterBtnSize:(CGSize)size center:(CGPoint)center image:(UIImage *)image {
[self.centerBtn setBackgroundImage:image forState:UIControlStateNormal];
self.centerBtn.frame = CGRectMake(0, 0, size.width, size.height);
self.centerBtn.center = center;
}
#pragma mark - Btn Click
- (void)centerBtnDidClick {
if (self.centerClick) {
self.centerClick();
}
}
//重写hitTest方法,去监听中间按钮的点击,目的是为了让凸出的部分点击也有反应
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
//判断当前手指是否点击到中间按钮上,如果是,则响应按钮点击,其他则系统处理
//首先判断当前View是否被隐藏了,隐藏了就不需要处理了
if (self.isHidden == NO) {
//将当前tabbar的触摸点转换坐标系,转换到中间按钮的身上,生成一个新的点
CGPoint newP = [self convertPoint:point toView:self.centerBtn];
//判断如果这个新的点是在中间按钮身上,那么处理点击事件最合适的view就是中间按钮
if ( [self.centerBtn pointInside:newP withEvent:event]) {
return self.centerBtn;
}
}
return [super hitTest:point withEvent:event];
}
@end
总结
- 方法一和方法二代码量最少,但灵活性比较差,如果按钮的位置超出了tabBar,那么就不适用了,所以前两种方法使用于
微博
、QQ空间
之类的App
- 方法三灵活性最强,也是这三个方法中代码量最多的,为了扩展性,我一般会选择方法三。该方法适用于像
喜马拉雅
,闲鱼
,转转
之类的App。