模态未设置的UINavigationBar外观

时间:2014-01-14 01:40:03

标签: ios uinavigationbar uiappearance uiactivityviewcontroller

我在appDelegate中使用以下代码在我的应用中设置UINavigationBar和状态栏的外观:

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

此代码正确地将所有内容的外观设置为白色,除非阻止第三方模式viewController,例如来自Dropbox API或来自UIActivityViewController的Mail / Message viewController。我已经提供了一些屏幕截图来展示它们的外观。

UIActivityViewController邮件: UIActivityViewController Mail

UIActivityViewController消息: UIActivityViewController Message

Dropbox API: Dropbox API

我尝试将其放入

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

以及

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

并且没有人在工作。

10 个答案:

答案 0 :(得分:3)

和你一样,我一直在试图改变UIActivityViewController的外观,以及它" sub"控制器。似乎在iOS7中外观API有点儿错误。 UIActivityViewController可能是一个不同的过程,并且肯定是一个单独的窗口,所以我并不感到惊讶它的风格很麻烦。

无论如何,我找到了解决这个问题的有趣方法,但你的设计师可能不喜欢它。创建UIWindow的子类(例如:MyWindow),将其实例化为主窗口,每次使用外观API时都使用它:

[UINavigationBar appearanceWhenContainedIn:[MyWindow class], nil].barTintColor = [UIColor redColor];

这样,您只会对实际属于您的应用程序的视图进行样式设置,Apple提供的视图将保持白/蓝。我想这不是你想要的解决方案,但另一方面它让用户很好地理解你的应用是什么以及系统提供的是什么;)

答案 1 :(得分:2)

在iOS 8中,UIActivityViewController在应用程序的根视图控制器上显示其各自的组合控制器。

您需要继承您的根视图控制器(无论是UIViewController还是UINavigationController)并添加以下代码。

@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

然后不是在AppDelegate或storyboard中初始化UINavigationController,而是初始化新的子类控制器。

其他一些建议是UIActivityViewController的子类,但这不起作用。

如果您想更改条形按钮和标题颜色,请在您的应用程序中使用以下内容: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]];

答案 2 :(得分:2)

我几个小时一直在努力解决这个问题,我的结论是来自UIActivityViewController的所有活动可能都有自己的风格实施,并且会依赖于它。

基本问题:您可以自定义某些内容以便查找邮件和邮件,但其他应用可能看起来不对。即:Facebook Messanger出于某种原因迫使状态栏变得轻松。

我的建议:创建UIWindow的子类,在您的应用程序中使用该子类,并将UIAppearance定位到该窗口类,并让系统的接口连接到只是:),(或稍微改变,如色彩)。

@interface MyWindow : UIWindow

@end

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

仅供参考:我们在使用UIActivityViewController时无法控制状态栏

希望这有帮助。

答案 3 :(得分:1)

由于到目前为止还没有解决方案,我做了以下操作,将UIActivityViewController模式的导航栏颜色设置为白色(因为我的应用程序的导航栏颜色为蓝色),这样用户至少可以看到按钮:

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

当用户完成UIActivityViewController模式后,应用程序的主导航栏颜色将返回蓝色。

希望有人会发布更好的解决方案。

答案 4 :(得分:1)

我找到了一个解决方案,可以更改发送取消按钮的文字颜色。

here检查我的回答。

答案 5 :(得分:0)

试试这个:

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

答案 6 :(得分:0)

我有同样的问题,我使用ActivityViewController的完成处理程序委托将我的条形色调颜色设置为白色这一行:

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

然而,这在iOS 8上不再起作用......他们改变了一点完成处理程序格式,代码已执行但颜色没有改变。

所以为了不浪费我所有的时间,我的快速解决方法是:

在显示共享控制器(带维护注释)

之前,我仍然使用此行更改全局颜色
[[UINavigationBar appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor darkGrayColor]}]; // Note : In ViewWillAppear the color is set back to white

在每个调用UIActivityViewController的视图控制器中,我在viewWillAppear方法中设置代码以获取颜色。

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

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

虽然代码中缺乏凝聚力,但效果很好。

答案 7 :(得分:0)

我使用walapu's answer制作了自己的解决方案。关键是,我在presentViewController:animated:completion:中也设置了导航栏色调颜色,而不是使用外观代理,而是直接用于MFMailComposeViewController。

- (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)animated completion:(void (^)(void))completion
{
    if ([viewControllerToPresent isKindOfClass:[MFMailComposeViewController class]]) {
        [((MFMailComposeViewController *)viewControllerToPresent).navigationBar setTintColor:[UIColor whiteColor]];
    }

    [super presentViewController:viewControllerToPresent animated:animated completion:^{
        if ([viewControllerToPresent isKindOfClass:[MFMailComposeViewController class]]) {
            [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
        }
        if (completion) {
            completion();
        }
    }];
}

答案 8 :(得分:0)

我特别对iMessage有问题。必须设置导航栏背景图像,设置色调不起作用。使用切片以我的颜色拉伸2x2像素图像。

[UINavigationBar.appearance setBackgroundImage:[UIImage imageNamed:@"red"] 
                                 forBarMetrics:UIBarMetricsDefault];

答案 9 :(得分:0)

这里,我在显示活动视图之前立即更改导航栏的全局外观,并在取消活动视图后将其重新更改。 (在iOS 12,Swift 5上测试)

body