Change navigation button color in MFMailComposerViewController on iOS 7

浪子不回头ぞ 提交于 2019-11-30 11:06:31

I used this and works perfect in 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]; 

Like OemerA says - there is no way to change the colors. My problem was that in UIAppearance I set the background color of the bar to blue so then the "buttons" are no longer visible. Since the email is actually not part of your app it makes more sense to reset the nag bar appearance prior to creating the mail composer. This is how I do it:

// 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]];

If you set the tintColor on UIWindow it works perfectly fine, the first time presenting the MFMailComposerViewController. It seems like it loses the tintColor information for the subsequent calls.

Note: this changes the tint of every element of your window.

If you ever inspect the view hierarchy created by showing a MFMailComposeViewController you'll see that it's contained within an instance of _UITextEffectsRemoteView. You have zero programmatic access to any subviews of that, which I'm guessing is because they're probably owned by a separate process. Those subviews will inherit anything set on the various UIAppearance proxies (e.g., bar background, titleTextAttributes, etc) but nothing more.

The UIAppearance protocol does not mention this in the documentation, but it does have this in the comments of the header file:

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.

So the end result is that while you can control most aspects of the appearance of MFMailComposeViewController you will always get the system default blue tint color.

Bug report: http://openradar.appspot.com/radar?id=6166546539872256

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)
}

As has been pointed out a few times, setting the tint on the MFMailComposeViewController navigation bar does not work. If you have other appearance changes set for the whole app, the tint colour is only one aspect of the issue, in our app we have changed the bar colour and UIBarButton text size so in the MFMailComposeViewController we see this:

The appearance in our app is set in a StyleGuide class with a function configureAppearanceModifiers called from the AppDelegate.

Taking the example from @timosdk I have added a second method:

- (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];

}

I call this before initialising the MFMailComposeViewController and then call configureAppearanceModifiers again in the didFinishWithResult delegate before dismissing the ViewController, this works perfectly.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!