1
votes

I made a subclass of UITabBarController that adds a custom UIView on top of tabs to replace the default badging on a UITabBarItem. I add these custom badgeviews on viewDidLoad of my custom UITabBarController.

[self.view addSubview:_tabBarItem1BadgeView];

The drawRect on my custom tabBarBadgeView looks like this:

- (void)drawRect:(CGRect)rect{

  CGContextRef ctx = UIGraphicsGetCurrentContext();
  // Badge
  CGSize size = self.frame.size;
  CGSize badgeSize = [self sizeThatFits:size];
  badgeSize.height = fminf(badgeSize.height, size.height);
  CGFloat x = roundf((size.width - badgeSize.width) / 2.0f);    
  CGRect badgeRect = CGRectMake(x, roundf((size.height - badgeSize.height) / 2.0f), badgeSize.width, badgeSize.height);
  CGContextAddEllipseInRect(ctx, rect);
  CGContextSetFillColor(ctx, CGColorGetComponents([_badgeColor CGColor]));
  CGContextFillPath(ctx);

  [_textLabel drawTextInRect:badgeRect];
}

Works great. I can see a badgeView exactly where I add it.If i switch around tabs, nothing is affected.

All of the tabControllers's view controllers are UINavigationControllers. I have one use case where one tab's UINavigationController's top most UIViewController should not show the tabBar, so I naturally set

controller.hidesBottomBarWhenPushed = YES

before pushing on the navigationController stack. This successfully suppresses the tabBar, but my custom UIViews continue to exist. To fix this, I made my custom UITabBarController a UINavigationControllerDelegate. This allows me to manually hide and show those custom UIViews when the navigation pushes and pops.

I do this using:

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController
                animated:(BOOL)animated

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated

Works great....only in iOS6.

On iOS7, the custom UITabBarController will not show the custom UIViews after popping back from a UIViewController that has hidesBottomBarWhenPushed set to YES. If hidesBottomBarWhenPushed is set to NO, the UIViews continue to appear.

In fact, I removed the UINavigationControllerDelegate entirely, and the odd thing happening is that when I drill down the stack on UINavigationController (with hidesBottomBarWhenPushed=YES), the tabBar is hidden, but the custom UIViews I added remain (something I expected). But when I pop back from that (and this is the oddest part), I get back to the tab's top level controller (which should show the tabBar), and the tabBar is visible(expected), but the custom UIViews disappear. Click back down, they appear, press back, they disappear.

And this behavior only happens on iOS7. Is there something that happens to the UITabBar differently after showing a UIViewController with hidesBottomBarWhenPushed = YES and then going back to a UIViewController with hidesBottomBarWhenPushed = NO?

1

1 Answers

2
votes

Your custom badge view is getting hidden behind UITabBarController's own views whenever UITabBarController re-adds its own views to its hierarchy.

To keep your custom badge view always on top, you can override drawRect on your custom badge view and call [self.superview bringSubviewToFront:self];

- (void)drawRect:(CGRect)rect {
  [self.superview bringSubviewToFront:self];

  // Other code...
}