在iOS 7上更改MFMailComposerViewController中的导航按钮颜色

19

我正在尝试更改MFMailComposerViewController中导航按钮的文本颜色,但它在iOS6上不像那样起作用。在iOS 6中,可以使用UIAppearance实现如下效果:

// Navigation button
UIBarButtonItem *barButton = [UIBarButtonItem appearance];
NSDictionary *barButtonTitleTextAttributes = @{UITextAttributeTextColor: [UIColor redColor]};
NSDictionary *disabledBarButtonTitleTextAttributes = @{UITextAttributeTextColor: [UIColor grayColor]};

[barButton setTitleTextAttributes:barButtonTitleTextAttributes forState:UIControlStateNormal];
[barButton setTitleTextAttributes:disabledBarButtonTitleTextAttributes forState:UIControlStateDisabled];
[barButton setBackgroundImage:[[UIImage imageNamed:@"btn_appearance"] stretchableImageWithLeftCapWidth:6 topCapHeight:0] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

但是在iOS 7上这并不起作用,看起来总是像这样:enter image description here

我也尝试在navigationBar上设置tintColor属性,但这也没有任何效果:

navigationBar.tintColor = [UIColor redColor];

在iOS 7上,是否有任何方法可以更改MFMailComposeViewController中导航按钮文本的颜色?


我在使用MFMailComposeViewController和UIAppearance时遇到了类似的问题... 在iOS 7中,它似乎完全失效了。 - liamnichols
请按照此方法操作。它的工作原理 https://dev59.com/WWEi5IYBdhLWcg3wLJtz#23088298 (y) - aqavi_paracha
6个回答

35
我在iOS7+上使用过这个,效果完美。
MFMailComposeViewController* mailViewController = [[MFMailComposeViewController alloc] init];        
mailViewController.mailComposeDelegate = self;
[mailViewController setToRecipients:@[@"email@apple.com"]];

[mailViewController.navigationBar setTintColor:[UIColor orangeColor]];

[self presentViewController:mailViewController animated:YES completion:nil]; 

4

就像OemerA所说的那样-没有办法改变颜色。我的问题是,我在UIAppearance中将栏的背景颜色设置为蓝色,因此“按钮”不再可见。由于电子邮件实际上不是您的应用程序的一部分,因此在创建邮件组合器之前重置nag栏外观更有意义。这是我做的方法:

// set to normal white
[[UINavigationBar appearance] setBarTintColor:[UIColor whiteColor]];
[[UINavigationBar appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor blackColor], NSForegroundColorAttributeName, nil]];

MFMailComposeViewController *mail = [[MFMailComposeViewController alloc] init];

// set to back to blue with white text
[[UINavigationBar appearance] setBarTintColor:[UIColor blueColor]];
[[UINavigationBar appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor whiteColor], NSForegroundColorAttributeName, nil]];

3
[mailViewController.navigationBar setTintColor:[UIColor orangeColor]];有效。 - Zorayr

3
如果您检查显示MFMailComposeViewController创建的视图层次结构,您会发现它包含在_UITextEffectsRemoteView实例中。您对该子视图没有任何编程访问权限,我猜测这是因为它们可能由单独的进程拥有。这些子视图将继承在各种UIAppearance代理上设置的任何内容(例如,bar背景,titleTextAttributes等),但不会更多。
UIAppearance协议在文档中没有提到这一点,但在头文件的注释中有此说明:
Note for iOS7: On iOS7 the tintColor property has moved to UIView, and now has special inherited behavior described in UIView.h.
This inherited behavior can conflict with the appearance proxy, and therefore tintColor is now disallowed with the appearance proxy.

因此,尽管您可以控制大多数MFMailComposeViewController外观方面的内容,但总会获得系统默认的蓝色色调。

错误报告: http://openradar.appspot.com/radar?id=6166546539872256


3
如果在UIWindow上设置了tintColor,第一次呈现MFMailComposerViewController时它可以很好地工作。似乎在后续调用中它会失去tintColor信息。
注意:这会更改窗口中每个元素的色调。

2
正如多次指出的那样,在MFMailComposeViewController导航栏上设置色调是无效的。如果您为整个应用程序设置了其他外观更改,则色调颜色只是问题的一个方面,在我们的应用程序中,我们已经更改了栏颜色和UIBarButton文本大小,因此在MFMailComposeViewController中我们看到这样的情况: Navigation bar style in MFMailComposeViewController 我们的应用程序外观是在StyleGuide类中设置的,该类具有一个名为configureAppearanceModifiers的函数,从AppDelegate中调用。
参考@timosdk的示例,我添加了第二种方法:
- (void)neutraliseAppearanceModifiers {

    [[UINavigationBar appearance] setTranslucent:NO];
    [[UINavigationBar appearance] setTintColor:nil];
    [[UINavigationBar appearance] setBarTintColor:[UIColor whiteColor]];
    [[UINavigationBar appearance] setBackIndicatorImage:nil];
    [[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:nil];
    [[UINavigationBar appearance] setBackgroundImage:nil
                                  forBarPosition:UIBarPositionAny
                                      barMetrics:UIBarMetricsDefault];
    [[UIBarButtonItem appearance] setTitleTextAttributes:nil forState:UIControlStateNormal];
    [[UIBarButtonItem appearance] setTitleTextAttributes:nil forState:UIControlStateHighlighted];
    [[UIBarButtonItem appearance] setTitleTextAttributes:nil forState:UIControlStateDisabled];
    [[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil] setTitleTextAttributes:nil forState:UIControlStateNormal];
    [[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil] setTitleTextAttributes:nil forState:UIControlStateHighlighted];
    [[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil] setTitleTextAttributes:nil forState:UIControlStateDisabled];

}

在初始化MFMailComposeViewController之前,我调用了这个方法,然后在didFinishWithResult代理中再次调用configureAppearanceModifiers来关闭视图控制器,这样可以完美地实现。


在初始化MFMailComposeViewController之前“中和”一些东西对我非常关键。感谢您! - Xeaza

1

Swift 3.0

func sendEmail() {
    if MFMailComposeViewController.canSendMail() {
        let mail = MFMailComposeViewController()
        mail.navigationBar.tintColor = UIColor.red
        mail.mailComposeDelegate = self
        mail.setToRecipients(["abc@abc.com"])
        mail.setMessageBody("<p>You're so awesome!</p>", isHTML: true)

        present(mail, animated: true)
    } else {
        // show failure alert
    }
}

func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
    controller.dismiss(animated: true)
}

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