UINavigationBar Appearance on Modal Not Setting

2019-02-16 18:25发布

I am using the following code in my appDelegate to set the appearance of my UINavigationBar and status bar throughout my app:

[[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];
[[UINavigationBar appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor whiteColor]}];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];

This code correctly sets the appearance of everything to white everywhere except when a third-party modal viewController is prevented, such as from the Dropbox API or the Mail/Message viewController from a UIActivityViewController. I've included some screenshots to show how these are looking.

UIActivityViewController Mail: UIActivityViewController Mail

UIActivityViewController Message: UIActivityViewController Message

Dropbox API: Dropbox API

I tried putting this in

[[UINavigationBar appearanceWhenContainedIn:[MFMailComposeViewController class], nil] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor whiteColor]}];

as well as

[[UINavigationBar appearanceWhenContainedIn:[UIActivityViewController class], nil] setTintColor:[UIColor whiteColor]];

and neither one is working.

9条回答
时光不老,我们不散
2楼-- · 2019-02-16 18:52

I've been struggling with this same issue for hours and my conclusion is that all activities from the UIActivityViewController may have their own style implementation and will look depending on that.

Basic problem: You can customise something to look ok for mail and messages, but other apps may look wrong. i.e: Facebook Messanger for some reason forces status bar to be light.

My recommendation: Create a subclass of UIWindow, use that subclass within your application and target UIAppearance to that window class and let the system's interfaces to just be :), (or with minor changes like tint color).

@interface MyWindow : UIWindow

@end

// further in code
[[UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[MyWindow class]]] setTintColor:[UIColor orangeColor]];

FYI: We have literally no control over status bar when using UIActivityViewController

Hope this helps.

查看更多
兄弟一词,经得起流年.
3楼-- · 2019-02-16 18:55

I have the same problem and I used ActivityViewController's completion handler delegate to set back my bar Tint color to white with this line :

shareViewController.completionWithItemsHandler = ^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *activityError) {
            [[UINavigationBar appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor]}];
        };

However this doesn't work anymore on iOS 8... They changed little bit the completion handler format, the code got executed but the color didn't change.

So in order not to waste all of my time here is my quick fix :

I am still changing the global color with this line just before showing the sharing controller (with comment for maintenance)

[[UINavigationBar appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor darkGrayColor]}]; // Note : In ViewWillAppear the color is set back to white

In each view controller that are calling a UIActivityViewController, I am setting in the viewWillAppear method the code to get the color back.

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    [[UINavigationBar appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor]}];
}

This works good although it produce lack of cohesion in the code.

查看更多
Anthone
4楼-- · 2019-02-16 18:56

Try this:

[[UINavigationBar appearance] setBarTintColor:[UIColor whiteColor]];
查看更多
迷人小祖宗
5楼-- · 2019-02-16 19:00

I found a solution to change the text color of the Send and Cancel buttons.

Check my answer from here.

查看更多
6楼-- · 2019-02-16 19:02

Since there is no solution until now, I did the following to set the color of navigation bar of UIActivityViewController modal to white (as my app's navigation bar color is blue) so that the users can at least see the buttons:

[[UINavigationBar appearance] setBarTintColor:[UIColor whiteColor]];

When the user is done with the UIActivityViewController modal, the app's main navigation bar color is returned to blue.

Hopefully somebody will post a better solution.

查看更多
Luminary・发光体
7楼-- · 2019-02-16 19:04

In iOS 8 the UIActivityViewController presents its individual compose controllers on the root view controller of your application.

You need to subclass your root view controller (whether it be a UIViewController or UINavigationController) and add the following code.

@interface UINavigationControllerBarColor : UINavigationController

@end

@implementation UINavigationControllerBarColor

- (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion {
    [super presentViewController:viewControllerToPresent animated:flag completion:^{
        [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
        if (completion) {
            completion();
        }
    }];
}

@end

and then instead of initializing a UINavigationController in the AppDelegate or storyboard, initialize your newly subclassed controller.

Some other recommendations subclass the UIActivityViewController but this does not work.

If you want to change the bar button and title colors as well use the following in your application:didFinishLaunching:

[[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];
[[UINavigationBar appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:
                                                      [UIColor whiteColor], UITextAttributeTextColor,
                                                      [UIFont systemFontOfSize:18.0f], UITextAttributeFont,
                                                      nil]];
[[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil] setTintColor:[UIColor whiteColor]];
查看更多
登录 后发表回答