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.