views:

3375

answers:

4

I've spent the past two days just trying to enable the sending of email from within my app. Hoping one of the smart folks on here can help me out. presentModalViewController doesn't work for me (just crashes the app with no explanation as to why), so I'm forced to add the view of MFMailComposeViewController. Here's my attempt:

MFMailComposeViewController *controller = [[MFMailComposeViewController alloc] init];
    controller.mailComposeDelegate = self;
    [controller setSubject:@"test subject"];
    [controller setMessageBody:@"this is the message body" isHTML:NO];

    // [self presentModalViewController:controller animated:YES]; //this crashes the app
//so I try this instead:     
    controller.view.frame = CGRectMake(0,0,480,320);
    [self.view addSubview:controller.view];
    [controller release];

What gets added to the screen is the subject bar only, with cancel and send buttons. None of the text fields (To:, Cc:, Subject, body) are displayed. Why aren't they a part of MFMailComposeViewController's view, and how can I display them?

A: 

You should instead try:

[[self navigationController] presentModalViewController...];

Since that's the proper way to present it. Trying to add its view manually is unfortunately utterly incorrect and will never work.

Adam Ernst
I'm not using a navigation controller. I tried that code anyway - it doesn't crash but nothing happens.
sol
You *must* use a navigation controller to use MFMailComposeViewController. The reason it does nothing is because if you're not using a navigation controller, [self navigationController] returns nil, and in Cocoa messages to nil are a no-op.
Adam Ernst
You shouldn't need to use a navigation controller. Adam, are you confusing 'presentModal' with 'pushViewController'? (The latter would require a navigationController.)
Greg Maletic
Greg, you're correct; I mean to say "you *must* use a UIViewController". The top-voted answer by Kailoa expresses my sentiment in a much clearer fashion.
Adam Ernst
+1  A: 

Honestly, you should be using presentModalViewController. Rather than force your way around the SDK, consider debugging the crash. Turn on the debugger and see if there are any exceptions logged in the console. Check for crash logs, etc...

Also, make sure that self is a proper delegate and a UIViewController subclass.

Kailoa Kadano
self is indeed a subclass of UIViewController and a proper delegate:@interface MenuViewController : UIViewController <MFMailComposeViewControllerDelegate>{ ...There are no exceptions logged when it crashes. That's why I'm at a complete loss here. I just get a black screen. Can I get crash logs from somewhere besides the console?
sol
check the Organizer in XCode.
Kailoa Kadano
also ~/Library/Logs/DiagnosticReports/
Kailoa Kadano
I have posted a debug image showing the code at the presentModalViewController line. There's a red hex value, but I'm not sure if that's a problem or not:http://img127.imageshack.us/img127/6329/picture2dla.png
sol
also, my app is landscape only. not sure if that causes problems with presentModalViewController.
sol
red hex just means the value was changed. doesn't mean anything bad. I'd try removing the landscape only restraint and see if that changes anything... presentModalViewController works like it should for all my apps and test projects.
Kailoa Kadano
A: 

Well I have determined that one must create a dummy view controller otherwise the darn thing won't slide in.

I create a class called Sys_Mail that is a @interface Sys_Mail : UIViewController

and then i create basically a root view view controller. I wrestled with portrait/landscape for hours but determined that if you attach the view controller to the top level view (which contains my landscape transform) then it slides in as a landscape window. There is just one visual glitch, the parent window gets moved around for a few seconds while the new window slides in, this is a side effect of the landscape transform doing odd things to the parent....

in order to get landscape orientation on the sliding window you must declare a method in your Sys_Mail class that handles the autorotate message:

//======================= // shouldAutorotateToInterfaceOrientation //======================= // see if this ever gets called for the view controller -(BOOL) shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation) interfaceOrientation { if (TRACE) printf ("shouldAutorotateToInterfaceOrientation\n"); return (interfaceOrientation == UIInterfaceOrientationLandscapeRight); // or whatever orientation is needed }

the variable gMasterView refers to my top level view (that has the landscape transform and is attached to the window). Subviews don't seem to work, view controllers are awful THEY ARE MORE DESIGN PATTERN CRAP. I want total control of my views not some microsoft MFC type crud!

Sys_Mail* g_root_vc;

if (g_root_vc == nil) { // create an empty view controller so we have something to work with g_root_vc = [[Sys_Mail alloc] init]; g_root_vc.view = (UIView*) gMasterView; }

so this

A: 

I have the same crash and finally I can fix it by sending presentModalViewController message to [self navigationController].

Here is my code:

// Create the Mail composer view controller
MFMailComposeViewController* controller = [[MFMailComposeViewController alloc] init];

// Set the view controller delegate
controller.mailComposeDelegate = self;

// Set recipients, if you want
[controller setToRecipients:recipients];

// Set subject, if you want
[controller setSubject:@"The subject"];

// Set message body, if you want
[controller setMessageBody:@"The message body" isHTML:YES]; // isHTML -> YES/NO depending the message body

// Present the view controller 
[[self navigationController] presentModalViewController:controller animated:YES];

// Memory management
[controller release];

I hope this can help!

Sebastian
Me also facing same problem, controller is becoming nil, "0x0" so that it crashes. I do not know why it is becoming nil and storing 0x0 address.
Madan Mohan