UITabBarController and UIActionSheet – 65% less hit point!

Ever noticed an app where the UIActionSheet’s bottom button doesn’t want to respond to your taps, unless you hit exactly in the top of the button? If you have a UITabBarController and want to display a UIActionSheet, you have to be careful with what view you show the UIActionSheet in.

If a UIActionSheet is shown in “self” or “self.view” and you got a UITabBarController behind it less than half of the last button will respond to taps:

UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"UIActionSheet Title" delegate:nil cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:@"Option 1", @"Option 2", nil];
actionSheet.actionSheetStyle = UIActionSheetStyleBlackTranslucent;
[actionSheet showInView:self];
[actionSheet release];

Here’s how much of the button will actually respond to taps:

Here’s what you need to do to fix it:

[actionSheet showInView:[[[UIApplication sharedApplication] windows] objectAtIndex:0]];

And what it does:

Colouring fun with moreNavigationController

When adding more than 5 view controllers to your UITabBarController, a “More” tab is automatically setup for you, which includes a view controller and even a modal view for letting the user edit the app’s tabs in the order they want.

By default, the navigation bars for both the moreNavigationController and the modal view (edit) are the Default blue, but changing these colours isn’t exactly straightforward.

Here’s an example of what we want to achieve:

I use an orange colour in one of my apps for the navigation bars and it just looks wrong when the more tab’s navigation bars are blue.

Changing the colour of the moreNavigationController is quite easy. After you alloc the UITabBarController, set the colour of the moreNavigationController:

tabBarController.moreNavigationController.navigationBar.tintColor = [UIColor orangeColor];

You can also use the barStyle property if you like:

tabBarController.moreNavigationController.navigationBar.barStyle = UIBarStyleBlackOpaque;

That wasn’t so hard. But the navigation bar for the modal view that pops up when the user taps “Edit” is still the default blue. So let’s change that as well:

First, if you haven’t already, make sure your AppDelegate implements the UITabBarControllerDelegate. Then add the optional delegate method willBeginCustomizingViewControllers: in your AppDelegate’s implementation file, and add the following lines of code:

– (void)tabBarController:(UITabBarController *)controller willBeginCustomizingViewControllers:(NSArray *)viewControllers {
    UIView *editView = [controller.view.subviews objectAtIndex:1];
    UINavigationBar *modalNavBar = [editView.subviews objectAtIndex:0];
    modalNavBar.tintColor = [UIColor orangeColor];
}

Again, it’s possible to set the barStyle property instead of the tintColor, but barStyle won’t give you all the colour options, of course.

Now that you have gained control of the modal view, you change more properties. By default, the navigation bar title says “Configure”, but you can change that as well, or how about the background colour? Here’s how:

– (void)tabBarController:(UITabBarController *)controller willBeginCustomizingViewControllers:(NSArray *)viewControllers {
    UIView *editView = [controller.view.subviews objectAtIndex:1];
    editView.backgroundColor = [UIColor grayColor];
    UINavigationBar *modalNavBar = [editView.subviews objectAtIndex:0];
    modalNavBar.tintColor = [UIColor orangeColor];
    modalNavBar.topItem.title = @"Edit Tabs";
}

Regarding the HIG… I am not sure if all this is allowed. I will be submitting an update with an orange coloured navigation bar for both those views, and I believe other apps have it (NY Times) so I don’t think it goes against the HIG.

However, I don’t think it’s a good idea to change the backgroundColor property of the “editView”. I tried with a grey colour and it doesn’t look right. It might also get your app rejected, because it’s such a big change. That your navigation bars are the same colour throughout your app only makes it look better in my opinion, rather than having a blue navigation bar clash with the rest of your beautifully designed app :)