Search code examples
iosobjective-ccocoa-touchuiappearance

UINavigationBar appearance proxy when contained in UIPopoverController


I'm doing something that supposed to work in iOS7 and 8, but for some reason it doesn't. I want to customize navigation bar properties via appearance proxy and want it to be applied to all navigation bars even the ones that are inside UIPopover.

So, first step I do the following:

UINavigationBar *appearance = [UINavigationBar appearance];
appearance.barTintColor = [UIColor redColor];
appearance.titleTextAttributes = @{
    NSForegroundColorAttributeName: [UIColor yellowColor]
};

This supposed to make all navigation bars red with yellow title. Works in iOS8. Mostly work in iOS7. For some reason when view controller is being presented inside UIPopoverController - it gets default appearance.

This is how I present popover (nothing fancy - almost standard sample code):

UIViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:@"vc2"];
vc.title = @"View Controller 2";
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
self.popover = [[UIPopoverController alloc] initWithContentViewController:nav];
[self.popover presentPopoverFromRect:CGRectMake(100, 100, 100, 100) inView:self.view permittedArrowDirections:0 animated:YES];

Ok, so I decided to try appearanceWhenContainedIn and explicitly set its appearance there. Added the following code to initial appearance customization:

appearance = [UINavigationBar appearanceWhenContainedIn:[UIPopoverController class], nil];
appearance.barTintColor = [UIColor greenColor];
appearance.titleTextAttributes = @{
    NSForegroundColorAttributeName: [UIColor blueColor]
};

Now. For some reason this last code doesn't affect anything. In iOS8 navigation bars inside UIPopoverControllers are still red + yellow, not green + blue, and iOS7 still uses default appearance.

What am I doing wrong here?

Here is link to the test project: https://dl.dropboxusercontent.com/u/6402890/TestAppearance.zip


Solution

  • For iOS 8

    NS_CLASS_AVAILABLE_IOS(8_0) @interface UIPopoverPresentationController : UIPresentationController
    

    Using the following worked for me. Navigation controller is contained in the UIPopoverPresentationController.

    appearance = [UINavigationBar appearanceWhenContainedIn:[UIPopoverPresentationController class], nil];
    

    For iOS 7

    appearance = [UINavigationBar appearanceWhenContainedIn:[UIPopoverController class], nil];
    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
    nav.navigationBar.barStyle = UIBarStyleBlack;
    

    If navigation controller is loaded from storyboard, barStyle is also needed to be set to UIBarStyleBlack in storyboard.