Override UIAppearance property for MFMailComposeViewController
Asked Answered
P

3

17

I am using the UIAppearance protocol to set the background image of UINavigationBar objects throughout my app.

[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"image-name"] forBarMetrics:UIBarMetricsDefault];

I would like to override this for instances of MFMailComposeViewController so that the default style navigation bar is displayed. I attempted to use appearanceWhenContainedIn to set this and this works on iOS 5 but not on iOS 6.

[[UINavigationBar appearanceWhenContainedIn:[MFMailComposeViewController class], nil] setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];

Am I making an error or is there a better way to accomplish this?

Pinstripe answered 22/3, 2013 at 21:48 Comment(2)
According to Apple Developer Support: It is a known bug in iOS 7.0.Faustino
this is fixed in iOS 9Connolly
D
24

Changing the appearance of a MFMailComposer through normal measures is not possible, but there is a little workaround you can do, which I've used many times before.

Add two methods to the class in which you wish to implement the new look to:

- (void)applyComposerInterfaceAppearance
{
    [[UINavigationBar appearance] setTintColor:[UIColor blueColor]];
}

- (void)applyGlobalInterfaceAppearance
{
    // My default color of choice
    [[UINavigationBar appearance] setTintColor:[UIColor redColor]];
}

Now in your show method, apply the special composer interface changes you'd like to make.

- (void)showMailComposer
{
    if ([MFMailComposeViewController canSendMail]) 
    {
        [self applyComposerInterfaceApperance];

        MFMailComposeViewController *viewController = [[MFMailComposeViewController alloc] init];
        viewController.mailComposeDelegate = delegate;
        [viewController setToRecipients:mailRecepients];
        [viewController setSubject:mailSubject];
        [viewController setMessageBody:messageBody isHTML:NO];
        [self presentModalViewController:viewController animated:YES];
    }
}

And in your delegate, change the interface back to the way it was.

- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
    // Do normal mail composer did finish stuff in here
    [self applyGlobalInterfaceAppearance];
}
Dock answered 22/3, 2013 at 22:15 Comment(3)
This is what I do in my own apps too. I have a pair of setAppearance and unsetAppearance methods in my app delegate that I can call anywhere to turn on and off all my UI customizations whenever I need to present a standard prebaked view controller (the mail controller, iPod library picker, etc).Ermentrude
@Ziconic, could you please tell me how you "unset" your uiappearance properties on the fly? thank youHap
in my condition this logic worked with setBarTintColor. not with seTintColor.Sheliasheline
R
2

The Mail Composer view is run in a different process under iOS 6 and cannot be tampered with directly (since the view is essentially inside another app). You cannot customize what it shows, it's the same for the Twitter & Facebook views.

Here is a more detailed description of remote view controllers: http://oleb.net/blog/2012/10/remote-view-controllers-in-ios-6/

Ration answered 22/3, 2013 at 21:53 Comment(3)
Even though it is run in a remote process, that is an implementation detail not exposed to the developer; as far as the developer is concerned, it looks the same as before. I would suggest filing a bug if it's not working; I know that the remote view controller mechanism does at least something with the UIAppearance mechanism, because I have crash logs down in there. :)Haymow
The main view is indeed in a different process but the navigation bar and the navigation controller it's in are in the same process as your app and are styled according to your UIAppearance customizations.Ermentrude
@BJHomer I filed a radar. Feel free to dupe. rdar://13490724Pinstripe
L
1

Simply set the tintColor on the MFMailComposeViewController instance:

[mailInstance.navigationBar setTintColor:[UIColor someColor]];
Lapstrake answered 11/9, 2014 at 18:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.