The iPhone 3.0 SDK introduced a number of cool new controllers, one of which was the MFMailComposeViewController
class.
And although – in and of itself – it does so much, like much of what we run into in this developer life, it leaves some things greatly to be desired.
Like, “why in the heck does it ** have ** to put the subject line in the navigation bar as a title? Don’t they ** know ** I have a cool custom nav bar that they’re totally puking over?!?!?!”
Don’t fret. There is a solution.
First, you’ll need to implement the following delegate in the .h file of the controller where you are implementing the mail composer:
MFMailComposeViewControllerDelegate
Next, you’ll need to implement some sort of event handler. Here’s mine:
-(IBAction)doEmail:(id)id {
if ([MFMailComposeViewController canSendMail]) { MFMailComposeViewController *controller = [[MFMailComposeViewController alloc] init]; controller.mailComposeDelegate = self; [controller setSubject:@"My Subject"]; [controller setMessageBody:@"My Body" isHTML:YES]; [self presentModalViewController:controller animated:YES];
[[controller navigationBar] setTintColor:[UIColor greenColor]]; UIImage *image = [UIImage imageNamed: @"custom_nav_background.png"]; UIImageView * iv = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,320,42)]; iv.image = image; iv.contentMode = UIViewContentModeCenter; [[[controller viewControllers] lastObject] navigationItem].titleView = iv; [[controller navigationBar] sendSubviewToBack:iv]; [iv release];
[controller release]; } else { UIAlertView* myAlert = [[UIAlertView alloc] initWithTitle:@"My App" message:[NSString stringWithFormat:@"You cannot send email at this time."] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [myAlert show]; [myAlert release]; } }
Finally, you’ll need to implement a method to dismiss the email composer after you cancel or send.
// Dismiss email composer UI on cancel / send
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error {
[self becomeFirstResponder];
[self dismissModalViewControllerAnimated:YES];
}
The bits that take care of the custom navigation bar (and incidentally, hiding the subject line title Apple insists on fobbing off on you) are in bold in the code above.
There are a few interesting details to note:
[[controller navigationBar] setTintColor:[UIColor greenColor]];
Will tint the Cancel and Send buttons to whatever color you like; in this example, I chose green. Use whatever you like here.
UIImage *image = [UIImage imageNamed: @"custom_nav_background.png"];
UIImageView * iv = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,320,42)];
iv.image = image;
iv.contentMode = UIViewContentModeCenter;
[[[controller viewControllers] lastObject] navigationItem].titleView = iv;
[[controller navigationBar] sendSubviewToBack:iv];
[iv release];
The code above loads an navigation bar image (320 x 42 pixels for iPhone 2G, 3G, and 3Gs; 640 x 84 pixels for retina display), and sets the titleView on the MFMailComposerViewController navigation bar to the UIImageView I constructed with my custom navigation bar background.
And last but definitely not least, we must send the custom titleView to the back so that we can “see” the Cancel and Send buttons.
The subject line will now no longer appear in the title bar – which is why I did this in the first place. It was totally jamming my chi.
Give it a try. I’d be interested in your feedback on this solution.
[[[controller viewControllers] lastObject] navigationItem].titleView = iv;
can be written as
controller.topViewController.navigationItem.titleView = iv;
LikeLike
good job buddy it worked perfectly for me
LikeLike
Do you have a solution for iOS 5? I can no longer get the default title “new message” on the nav bar to go away. My custom background image shows, but I have a logo in the center and “new message” is displaying over top of it
LikeLike
Great job buddy. Your tut is easy to understand and worked for me. Thanks
LikeLike
can we change the title of the send and cancel button of navigation bar of MFMailComposeViewController
LikeLike
You might be able to by walking the chain of subviews… but my guess would be that Apple would frown upon changing the buttons on a standard view controller.
LikeLike
Thanks for sharing this wonderful post. I was trying to do the same in my app.. Thanks to guide. Keep it up.
LikeLike
Can you or anyone comment on if changes like this would be accepted by Apple? I’ve seen various comments going both ways.
Thanks
LikeLike
This is not working in iOS 7
LikeLiked by 1 person
can we change from field?
LikeLike
No.
LikeLike