问题解决:自动隐藏UITabBar上面的自定义按钮

在UITabBar中间添加按钮,像下图:


实现如下:

// 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





你可能感兴趣的:(问题解决:自动隐藏UITabBar上面的自定义按钮)