I have a weird bug in both iOS 6 and 7 with the following UITabBarController
subclass code:
self.viewControllers = @[self.myKitchenNavigationController,
self.photosIndexNavigationController,
self.postNavigationController,
self.feedNavigationController,
self.talkNavigationController];
self.selectedIndex = 0;
// self.selectedViewController = self.myKitchenNavigationController; // This doesn't help either
If I programmatically set viewControllers
(previously nil
) and immediately set a selectedIndex
then the tab bar appears with no selection.
I had the impression that setting a selected index just after modifying the controllers was somehow "too" soon, so I wrapped that call inside a dispatch_async
call:
// Fix selection by dispatching async
dispatch_async(dispatch_get_main_queue(), ^
{
self.selectedIndex = 0;
});
Now it works, but I wonder if this is a SDK long-standing bug.
Actually the bug is still there, the full method:
- (void)setMode:(RootViewControllerMode)mode
{
if (_mode == mode)
return;
NBULogInfo(@"%@ %d", THIS_METHOD, mode);
_mode = mode;
switch (mode)
{
case RootViewControllerLoggedMode:
{
self.viewControllers = @[self.myKitchenNavigationController,
self.photosIndexNavigationController,
self.postNavigationController,
self.feedNavigationController,
self.talkNavigationController];
// Fix selection by dispatching async
dispatch_async(dispatch_get_main_queue(), ^
{
self.selectedIndex = 0;
});
// Adjust post button
self.postButtonHidden = NO;
[self.view addSubview:self.postButton];
break;
}
case RootViewControllerNotLoggedMode:
{
self.viewControllers = nil;
// Remove post button to tabBar
[self.postButton removeFromSuperview];
break;
}
default:
case RootViewControllerEmptyMode:
{
self.viewControllers = nil;
break;
}
}
}
This is the only code that touches the tab bar controller's viewControllers
and the current selected tab.
Already verified this was called on the main thread, then also tried wrapping everything inside dispatch_async
in the main queue, and finally tried dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue()
, and still the problem persists.
Modifying the tab bar's viewControllers
seems to be quite bug-prompt, besides the problem here also tab item badges appear sometimes behind the selectionIndicatorImage
.
We end up setting the controllers in a storyboard and avoid modifying the controller's or their order.