实现如下:
// Create a custom UIButton and add it to the center of our tab bar
-(void) addCenterButtonWithImage:(UIImage*)buttonImage highlightImage:(UIImage*)highlightImage
{
UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
button.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleTopMargin;
button.frame = CGRectMake(0.0, 0.0, buttonImage.size.width, buttonImage.size.height);
[button setBackgroundImage:buttonImage forState:UIControlStateNormal];
[button setBackgroundImage:highlightImage forState:UIControlStateHighlighted];
CGFloat heightDifference = buttonImage.size.height - self.tabBar.frame.size.height;
if (heightDifference < 0)
button.center = self.tabBar.center;
else
{
CGPoint center = self.tabBar.center;
center.y = center.y - heightDifference/2.0;
button.center = center;
}
[self.view addSubview:button];
}
如果我们要导航到下一层并且要隐藏底部的UITabBar,代码如下:
UIViewController *vc = [[UIViewController alloc] init];
vc.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:vc animated:YES];
通过将hidesBottomBarWhenPushed属性设置为YES,压栈的时候可以把UITabBar隐藏,但是中间的按钮并没有被隐藏。这里有两种解决方法:
一、提供方法手工隐藏/显示中间按钮,显示的时候触发动画
- (void)hideTabBar:(BOOL)hidden {
UIButton *btn = (UIButton *)[self.tabBarController.view viewWithTag:kCENTER_BUTTON_TAG];
[[btn layer] removeAnimationForKey:kANIMATION_KEY];
if (btn.hidden) {
CATransition *animation = [CATransition animation];
animation.delegate = self;
animation.duration = 0.35;// 0.618
animation.timingFunction = UIViewAnimationCurveEaseInOut;
animation.type = kCATransitionFade;
[[btn layer] addAnimation:animation forKey:kANIMATION_KEY];
}
btn.hidden = hidden;
}
二、自动隐藏
1、实现UINavigationControllerDelegate协议,为UITabBarController的viewControllers注册协议
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
if (viewController.hidesBottomBarWhenPushed) {
[self hideTabBar:viewController.hidesBottomBarWhenPushed];
}
}
[self.tabBarController.viewControllers enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
UINavigationController *navVC = obj;
navVC.delegate = self;
}];
2、注册UITabBar的hidden的kvo
[self.tabBarController addObserver:self forKeyPath:@"tabBar.hidden" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([keyPath isEqualToString:kTABBAR_HIDDEN_KEYPATH]) {
[self hideTabBar:self.tabBar.hidden];
}
}
思路:
1、因为设置hidesBottomBarWhenPushed为YES,导致UITabBar的hidden属性变化,所以一开始希望通过注册UITabBar的hidden的kvo来实现自动隐藏/显示中间按钮,但是在UINavigationController压栈完成后才触发kvo事件,导致进入下一层里面才调用隐藏中间按钮的方法;
2、接着就实现UINavigationControllerDelegate协议,为UITabBarController的viewControllers注册协议,在UINavigationController压栈的时候触发方法navigationController:willShowViewController:animated,判断hidesBottomBarWhenPushed属性设置如果设置为YES,则直接隐藏中间按钮;
3、结果是只要在UINavigationController压栈的时候设置viewController的hidesBottomBarWhenPushed属性为YES,压栈的时候就可以直接隐藏中间按钮,出栈的时候触发中间按钮的显示动画。
在UITabBar中间添加按钮的实现:https://github.com/boctor/idev-recipes
例子代码下载地址:http://vdisk.weibo.com/s/s_B6F