在iOS7中,当从UIActivityViewController中呈现邮件组合器时,无法设置发送和取消按钮的文本颜色。

68
我正在使用UIActivityViewController在iOS7上分享项目。当我点击邮件选项时,会弹出邮件撰写器,但是导航栏上的取消和发送按钮以及导航栏本身都是蓝色的,使得它们很难阅读,所以我想要改变它们的颜色。在iOS6中可以工作,但在iOS7中不行。
我已经尝试过。
[[UIBarButtonItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor redColor], UITextAttributeTextColor, [UIColor clearColor], UITextAttributeTextShadowColor, nil] forState:UIControlStateNormal];

它在iOS6中可用,我已经尝试过。

[[UIBarButtonItem appearance] setTintColor:[UIColor redColor]];
[[UINavigationBar appearance] setBarTintColor:[UIColor redColor]];

在应用程序第一次运行时,它会导致颜色闪烁为红色,然后立即切换回蓝色。


1
我遇到了同样的问题。希望有人知道是怎么回事。 - Kevin_TA
这里也有同样的问题...你找到解决方案/解决方法了吗? - rgomesbr
1
我不知道你是否还在关注这个问题,但是我给出了一个解决方案。iOS 7按钮颜色是使用导航栏的色调颜色设置的。 - Kevin van Mierlo
20个回答

76

成功更改了 MFMailComposerViewController 中的 SendCancel 按钮的文本颜色(发送和取消),以及在从 UIActivityViewController 呈现时仅更改 MFMessageComposeViewController 中的 Cancel 按钮。

使用 UIActivityViewController,点击 Message 或者 Mail

Using an UIActivityViewController

您会注意到 SendCancel 按钮的默认文本颜色是蓝色的:

Default blue colors

为了改变这种颜色,在 AppDelegate.m 类中的 didFinishLaunchingWithOptions 方法中插入以下代码行:

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

这将导致:

更改为白色

您也可以使用其他颜色,例如:

[UIColor purpleColor];

更改为紫色

[UIColor greenColor];

更改为绿色

我如何测试这个?我发现这个解决方案适用于以下情况:

  • 使用Xcode 5.1,在iOS 7.1模拟器中构建,基础iOS SDK为7.1(可以从选择项目文件 -> Build Settings -> Base SDK进行选择。同时,从常规->部署目标-> 7.1进行选择);
  • 使用Xcode 5.1,在iPhone 4上构建,基础iOS SDK为7.0(可以从选择项目文件 -> Build Settings -> Base SDK进行选择。同时,从常规->部署目标-> 7.0进行选择);
  • 使用Xcode 5.1,在iPhone 4上构建,基础iOS SDK为7.1(可以从选择项目文件 -> Build Settings -> Base SDK进行选择。同时,从常规->部署目标-> 7.1进行选择);

当测试以下情况时,它不起作用:

  • 使用Xcode 5.1,在iOS 7.0模拟器中构建,基础iOS SDK为7.0(可以从选择项目文件 -> Build Settings -> Base SDK进行选择。同时,从常规->部署目标-> 7.0进行选择);

因此,使用它应该是安全的,因为我认为实际设备上的行为比iOS模拟器中的行为更重要。如果有人知道它在iOS 7.0模拟器中为什么不起作用,我想知道。 :)


2
我尝试在Xcode 5.1 iOS 7.1模拟器和iPhone 5s iOS 7.1上运行它,但它没有起作用。 - dwery
可以在iOS 7.1设备上运行,但无法在iOS 7.0设备上运行。通过@paillou下面的答案解决了问题。 - instaable
对于Swift应用程序,相当于在AppDelegate中使用UINavigationBar.appearance().tintColor = UIColor.whiteColor()(我认为需要直接复制UINavigationBarButtonItem - Marcus Hooper
仍然无法更改状态栏颜色 :( - Michael
它不起作用,你能提供一些代码建议吗?我正在使用TabBar控制器。 - Thangavel
1
这段代码在iOS 11上的Swift 4中对我有效:UIBarButtonItem.appearance(whenContainedInInstancesOf: [UINavigationBar.self]).tintColor = UIColor.white - ekscrypto

25

在 UIActivityViewController 中更改导航栏着色和状态栏着色。 Swift 3 解决方案:

extension MFMailComposeViewController {
    override open func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        UIApplication.shared.statusBarStyle = UIStatusBarStyle.lightContent
    }

    open override func viewDidLoad() {
        super.viewDidLoad()
        navigationBar.isTranslucent = false
        navigationBar.isOpaque = false
        navigationBar.barTintColor = UIColor.white
        navigationBar.tintColor = UIColor.white
    }
}

已确认在iOS10上运行正常,无论是原样还是适配Swift 2.3。 - alasker
你可以自由地删除UIStatusBarStyle和UIColor,只留下.lightContent和.white。 - alasker
最佳且更优雅的解决方案。可以使用按钮,但由于某种原因我无法使其在iOS10中与barTint一起工作。 - rmvz3
要更改标题的颜色,请添加let whiteColor = UIColor.white let attributedStringColour : NSDictionary = [NSForegroundColorAttributeName : whiteColor] navigationBar.titleTextAttributes = attributedStringColour as? [String : AnyObject] - webjunkie
1
我认为我们不应该在扩展中覆盖方法。 - Edward Huynh

6

以下是截至今日在iOS 7.1上可用的解决方案。

继承UIActivityViewController并重写以下方法:

- (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion
{
    viewControllerToPresent.view.tintColor = [UIColor whiteColor];

    [super presentViewController:viewControllerToPresent animated:flag completion:^{
        [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];

        if (completion) {
            completion();
        }
    }];
}

这将使按钮变为白色,状态栏也变为白色。

这是我在整个互联网上看到的所有建议中唯一有效的解决方案 - 感谢@Macijej! - thgc

4

对于 Swift:

self.navigationController?.presentViewController(activityViewController, animated: true, completion: { () in
   UIBarButtonItem.appearance().tintColor = UIColor.whiteColor()
   UINavigationBar.appearance().barTintColor = UIColor.whiteColor() // optional to change bar backgroundColor           
}

这将会把发送取消按钮的颜色改为白色(在iOS 7,8上测试过),但我仍然不能让状态栏文本颜色变为白色。(虽然我没有尝试过使用子类化UIActivityViewController的解决方案来改变状态栏文本颜色)

好的,我很久以前就完成了这个项目,没有在最新版本上进行测试。如果有人对最新的iOS版本有解决方案,请建议修改。我会更新我的答案。 - Aks

4

我通过扩展UIActivityViewController并重写viewWillAppearviewWillDisappear方法解决了我的问题:

extension UIActivityViewController {

    override open func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        UINavigationBar.appearance().barTintColor = .white
    }
        
    open override func viewDidLoad() {
        super.viewDidLoad()
        navigationController?.navigationBar.isTranslucent = false
        navigationController?.navigationBar.isOpaque = false
        navigationController?.navigationBar.barTintColor = UIColor(red: (247/255), green: (247/255), blue: (247/255), alpha: 1)
        //navigationBar.tintColor = UIColor.white
    }

    open override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(true)
        UINavigationBar.appearance().barTintColor = mycustomColor
    }

}

3

我曾经遇到了一个与应用程序相关的问题,即由于外观代理的影响,UINavigationBartintColor属性在任何地方都是白色的。结果就是邮件撰写视图控制器navigationBar上的UIBarButtonItem不可见(白色按钮在白色navigationBar上)。

我在我的application:didFinishLaunchingWithOptions:方法中调用了以下代码:

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

由于现在(暂时)无法访问UIActivityViewController中邮件撰写视图控制器的UINavigationBar,我采用了以下受Alex答案启发的解决方法:
UIColor *normalColor = [[UINavigationBar appearance] tintColor];
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:dataToShare applicationActivities:nil];
            [activityViewController setCompletionHandler:^(NSString *activityType, BOOL completed) {
                // back to normal color
                [[UINavigationBar appearance] setTintColor:normalColor];
            }];
            [self presentViewController:activityViewController animated:YES completion:^{
                // change color temporary
                [[UINavigationBar appearance] setTintColor:[UIColor colorWithRed:232.0f/255.0f green:51.0f/255.0f blue:72.0f/255.0f alpha:1.0f]];
            }];

注:此代码适用于iOS 7,但您可以在iOS 6中使用[[UIBarButtonItem appearance] setTintColor:](参见Kevin van Mierlo的答案)


3
这似乎是iOS 7的一个错误。我在网上看到了其他类似的报告,而且在iOS 7.1中也没有修复这个问题。
具体来说,无论你做什么,都不能为从UIActivityViewController显示的对话框设置导航栏的色调颜色。

1

这对我有用:

在AppDelegate.m文件中的函数中:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

我已经输入了以下代码:
//mail composer
[[UINavigationBar appearanceWhenContainedIn:[MFMailComposeViewController class], nil] setBarTintColor:myBackgroundColor];
[[UINavigationBar appearanceWhenContainedIn:[MFMailComposeViewController class], nil] setTintColor:myBarItemsColor];

它在iOS7 + iOS8上运行良好,未在更新版本上尝试过。

1
在iOS 9.2上对我没用,导航栏按钮仍然是标准的蓝色。 - Michael DePhillips
1
@Michael 我写这个答案的时候,iOS8是最新版 - 已编辑答案 - Eliktz

1

我无法让Alex的解决方案起作用,但是我成功地得到了Paillou答案的变体,尽管在我的情况下我不得不设置barTintColor和titleTextAttributes两个属性:

UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:applicationActivities];

activityViewController.excludedActivityTypes = @[UIActivityTypePrint, UIActivityTypeCopyToPasteboard, UIActivityTypeAssignToContact, UIActivityTypeSaveToCameraRoll, UIActivityTypeAddToReadingList, UIActivityTypePostToVimeo, UIActivityTypePostToFlickr, UIActivityTypeAirDrop];

[activityViewController setCompletionHandler:^(NSString *activityType, BOOL completed) {
    // back to normal color
    [[UINavigationBar appearance] setBarTintColor:AAColorInputBorder];
    [[UINavigationBar appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:
                                                         [UIFont fontWithName:@"Avenir-Medium" size:18], NSFontAttributeName,
                                                         [UIColor whiteColor], NSForegroundColorAttributeName,
                                                         nil]];
}];

[self presentViewController:activityViewController animated:YES completion:^{
// change color temporary
[[UINavigationBar appearance] setBarTintColor:[UIColor whiteColor]];
[[UINavigationBar appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:
                                                     [UIFont fontWithName:@"Avenir-Medium" size:18], NSFontAttributeName,
                                                     AAColorInputBorder, NSForegroundColorAttributeName,
                                                     nil]];

感谢 Paillou!


我不知道为什么让事情正确地运行起来如此复杂,但这是我唯一的解决方案。我想知道像ShareKit这样的库是如何做到的... - dulgan

1

如果你想设置 iOS 7 中取消和发送按钮的颜色,你应该使用以下代码:

// Change the colours of the buttons in iOS 7
[[UINavigationBar appearance] setTintColor:[UIColor redColor]];

在iOS 6中,确实是这样的,你还应该在你的代码中保留这个。
// Change the colours of the buttons in iOS 6
[[UIBarButtonItem appearance] setTintColor:[UIColor redColor]];

// Change the color of the the navigation bar in iOS 6 and 7
[[UINavigationBar appearance] setBarTintColor:[UIColor redColor]];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接