自定义效果:
实现方法:
1、继承UITabBar并自定义样式
.h 文件
#import <UIKit/UIKit.h>
@interface KYCustomTabBar : UITabBar
@end
自定义实现部分代码:
#import "KYCustomTabBar.h"
@interface KYCustomTabBar ()
/** 中间突出的item */
@property (nonatomic, strong) UIButton *centerBtn;
@end
@implementation KYCustomTabBar
#pragma mark - Getter
- (UIButton *)centerBtn {
if (!_centerBtn) {
_centerBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 80, 60)];
[_centerBtn setImage:[UIImage imageNamed:@"centerIcon"] forState:UIControlStateNormal];
[_centerBtn addTarget:self action:@selector(clickCenterBtn:) forControlEvents:UIControlEventTouchUpInside];
}
return _centerBtn;
}
#pragma mark - 初始化
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
// 设置tabBarItem选中状态时的颜色
self.tintColor = [UIColor redColor];
// 添加中间按钮到tabBar上
[self addSubview:self.centerBtn];
}
return self;
}
// 重新布局tabBarItem(这里需要具体情况具体分析,本例是中间有个按钮,两边平均分配按钮)
- (void)layoutSubviews {
[super layoutSubviews];
// 把tabBarButton取出来(把tabBar的SubViews打印出来就明白了)
NSMutableArray *tabBarButtonArray = [NSMutableArray array];
for (UIView *view in self.subviews) {
if ([view isKindOfClass:NSClassFromString(@"UITabBarButton")]) {
[tabBarButtonArray addObject:view];
}
}
CGFloat barWidth = self.bounds.size.width;
CGFloat barHeight = self.bounds.size.height;
CGFloat centerBtnWidth = CGRectGetWidth(self.centerBtn.frame);
CGFloat centerBtnHeight = CGRectGetHeight(self.centerBtn.frame);
// 设置中间按钮的位置,居中,凸起一丢丢
self.centerBtn.center = CGPointMake(barWidth / 2, barHeight - centerBtnHeight/2 - 5);
// 重新布局其他tabBarItem
// 平均分配其他tabBarItem的宽度
CGFloat barItemWidth = (barWidth - centerBtnWidth) / tabBarButtonArray.count;
// 逐个布局tabBarItem,修改UITabBarButton的frame
[tabBarButtonArray enumerateObjectsUsingBlock:^(UIView * _Nonnull view, NSUInteger idx, BOOL * _Nonnull stop) {
CGRect frame = view.frame;
if (idx >= tabBarButtonArray.count / 2) {
// 重新设置x坐标,如果排在中间按钮的右边需要加上中间按钮的宽度
frame.origin.x = idx * barItemWidth + centerBtnWidth;
} else {
frame.origin.x = idx * barItemWidth;
}
// 重新设置宽度
frame.size.width = barItemWidth;
view.frame = frame;
}];
// 把中间按钮带到视图最前面
[self bringSubviewToFront:self.centerBtn];
}
#pragma mark - Actions
- (void)clickCenterBtn:(UIButton *)sender {
NSLog(@"点击了中间的按钮");
}
#pragma mark - UIViewGeometry
// 重写hitTest方法,让超出tabBar部分也能响应事件
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
if (self.clipsToBounds || self.hidden || (self.alpha == 0.f)) {
return nil;
}
UIView *result = [super hitTest:point withEvent:event];
// 如果事件发生在tabbar里面直接返回
if (result) {
return result;
}
// 这里遍历那些超出的部分就可以了,不过这么写比较通用。
for (UIView *subview in self.subviews) {
// 把这个坐标从tabbar的坐标系转为subview的坐标系
CGPoint subPoint = [subview convertPoint:point fromView:self];
result = [subview hitTest:subPoint withEvent:event];
// 如果事件发生在subView里就返回
if (result) {
return result;
}
}
return nil;
}
@end
2、继承UITabBarController管理多视图
重点在下方代码14行那句话,实现自定义
#import "KYTabBarController.h"
#import "KYCustomTabBar.h"
@interface KYTabBarController ()
@end
@implementation KYTabBarController
#pragma mark - Life Cycle
- (void)viewDidLoad {
[super viewDidLoad];
// 利用KVO来使用自定义的tabBar
[self setValue:[[KYCustomTabBar alloc] init] forKey:@"tabBar"];
[self addAllChildViewController];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Private Methods
// 添加全部的 childViewcontroller
- (void)addAllChildViewController {
UIViewController *homeVC = [[UIViewController alloc] init];
homeVC.view.backgroundColor = [UIColor redColor];
[self addChildViewController:homeVC title:@"首页" imageNamed:@"tabBar_home"];
UIViewController *activityVC = [[UIViewController alloc] init];
activityVC.view.backgroundColor = [UIColor yellowColor];
[self addChildViewController:activityVC title:@"活动" imageNamed:@"tabBar_activity"];
UIViewController *findVC = [[UIViewController alloc] init];
findVC.view.backgroundColor = [UIColor blueColor];
[self addChildViewController:findVC title:@"发现" imageNamed:@"tabBar_find"];
UIViewController *mineVC = [[UIViewController alloc] init];
mineVC.view.backgroundColor = [UIColor greenColor];
[self addChildViewController:mineVC title:@"我的" imageNamed:@"tabBar_mine"];
}
// 添加某个 childViewController
- (void)addChildViewController:(UIViewController *)vc title:(NSString *)title imageNamed:(NSString *)imageNamed {
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
// 如果同时有navigationbar 和 tabbar的时候最好分别设置它们的title
vc.navigationItem.title = title;
nav.tabBarItem.title = title;
nav.tabBarItem.image = [UIImage imageNamed:imageNamed];
[self addChildViewController:nav];
}
@end