要自定义一个tabbarController那肯定要先继承UITabBarController了,然后在tabbarController中设置子控制器。
设置子控制器需要以下几个步骤:
1. 设置子控制器的文字
childVc.title = title;// 同时设置tabbar和navigationBar的文字
2. 设置子控制器的图片
childVc.tabBarItem.image = [UIImage imageNamed:image];
childVc.tabBarItem.selectedImage = [[UIImage imageNamed:selectedImage]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];//UIImageRenderingModeAlwaysOriginal 这个是总是用原图片,如果不设置这个的话tabbar默认都是蓝色的
3. 设置文字的样式
NSMutableDictionary *textAttrs = [NSMutableDictionary dictionary];
textAttrs[NSForegroundColorAttributeName] = [UIColor grayColor];
NSMutableDictionary *selectTextAttrs = [NSMutableDictionary dictionary];
selectTextAttrs[NSForegroundColorAttributeName] = [UIColor redColor];
[childVc.tabBarItem setTitleTextAttributes:textAttrs forState:UIControlStateNormal];
[childVc.tabBarItem setTitleTextAttributes:selectTextAttrs forState:UIControlStateSelected];
3.1 先给外面传进来的小控制器 包装 一个导航控制器 (也可以不设置,看自己心情)
FFNavigationController *nav = [[FFNavigationController alloc] initWithRootViewController:childVc];
4. 添加为子控制器
[self addChildViewController:nav];
以上都做完了可以通过kvc自定义一个自己的tabbar,要设置自己的tabbar只能通过kvc来设置,因为UITabBarController的tabbar是readonly的,不能直接设置
//UITabBarController的属性
@property(nonatomic,readonly) UITabBar *tabBar NS_AVAILABLE_IOS(3_0); // Provided for -[UIActionSheet showFromTabBar:]. Attempting to modify the contents of the tab bar directly will throw an exception.
FFTabBar *tabBar = [[FFTabBar alloc] init];
tabBar.addbtnDelegate = self;
/** KVC */
[self setValue:tabBar forKey:@"tabBar"];
tabbarController基本就这样了,现在看看tabBar里是怎样的
在- (void)layoutSubviews给tabbar重新布局
先添加中间大按钮 (这个按钮可以换成自己喜欢的样子,这边只是随便搞了下,大概有个样子而已)
UIButton *addBtn = [UIButton buttonWithType:UIButtonTypeCustom];
addBtn.backgroundColor = [UIColor redColor];
[addBtn addTarget:self action:@selector(addClickAction) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:addBtn];
self.addBtn = addBtn;
CGFloat addBtnViewWidth = self.frame.size.width / count;
CGFloat addBtnViewHeight = self.frame.size.height + 50;
CGFloat addBtnViewX = (self.frame.size.width - addBtnViewWidth) * 0.5;
CGFloat addBtnViewY = -50;
addBtn.frame = CGRectMake(addBtnViewX, addBtnViewY, addBtnViewWidth, addBtnViewHeight);
确定了中间的大按钮之后,然后旁边的UITabBarButton的位置需要重新设置一下
NSUInteger idx = 0;
for (UIView *childView in self.subviews) {
Class class = NSClassFromString(@"UITabBarButton");
if ([childView isKindOfClass:class]){
if (idx == count / 2) idx++;
CGFloat cvX = idx * self.frame.size.width / count;//count是表示tabbar上一共有几个按钮
childView.frame = CGRectMake(cvX, 0, self.frame.size.width / count, self.frame.size.height);
idx++;
}
}
因为大button搞了超过tabbar的高度了所以要重写一下hitTest方法,这个方法可以超出父控件的范围仍然响应点击事件
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
UIView * view = [super hitTest:point withEvent:event];
if (view == nil) {
// 转换坐标系
CGPoint newPoint = [self.addBtn convertPoint:point fromView:self];
// 判断触摸点是否在button上
if (CGRectContainsPoint(self.addBtn.bounds, newPoint)) {
view = self.addBtn;
}
}
return view;
}
这样tabbar上的item就基本设置完成了,再做个代理把中间按钮的点击事件放开出去就基本完成了