Locking the Fields in MFMailComposeViewController

Jack Nutkins picture Jack Nutkins · Jun 8, 2011 · Viewed 18.8k times · Source

Is it possible to somehow lock the fields in an MFMailComposeViewController so that the body, recipients etc cannot be changed by the user? I need the e-mail the user sends to go to a particular account and the body to meet certain criteria so if the user drastically edits the format everything could go horribly wrong..At the moment the body is filled in from data that the user inputs to textfields and date-pickers in the previous view.

Basically I think it would just be more professional to have the fields locked rather than display an alert or something saying "Please Don't Edit the Message", so its not a massive problem if the fields can't be locked, but any help would be greatly appreciated.

Answer

Louie picture Louie · Jun 9, 2011

Download the framework from the link below. Then I have put together some code that sends the email with a nice "please wait" overlay. I have attached an image of what this looks like while its running (for the few seconds it takes). Please note, I take no credit for creating the SMTP framework. It was downloaded from the internet after searching for it forever. The zip file that you can download includes the overlay images that I created for user feedback. It has both @2x and regular. You will have to go into interface builder and create the label though that says "sending test drive..". Its already in the code but I didnt add it from code. So youll have to add it in IB.

1. Make sure to add the framework you downloaded to your project.

2. Make sure to add the CFNetwork framework to your project

3. Make sure to attach the UILabel name "loadingLabel" in interface builder

4. The username and password that the code is refering to is an smtp server. If you dont have one create a gmail account and use gmail settings. If you are not familiar with gmail settings google "gmail smtp" you will find what you need.

Find Framework & Art here

For your .h file make sure to include:

//for sending email alert
UIActivityIndicatorView * spinner;
UIImageView * bgimage;
IBOutlet UILabel * loadingLabel;

}
@property (nonatomic, retain)IBOutlet UILabel * loadingLabel;
@property (nonatomic, retain)UIImageView * bgimage;
@property (nonatomic, retain)UIActivityIndicatorView * spinner;
-(void)sendEmail;
-(void)removeWaitOverlay;
-(void)createWaitOverlay;
-(void)stopSpinner;
-(void)startSpinner;

For your .m file include:

@synthesize bgimage,spinner,loadingLabel;

// add this in ViewDidLoad
//set loading label to alpha 0 so its not displayed
loadingLabel.alpha = 0;

everything else is its own function

-(void)sendEmail {


    // create soft wait overlay so the user knows whats going on in the background.
    [self createWaitOverlay];

    //the guts of the message.
    SKPSMTPMessage *testMsg = [[SKPSMTPMessage alloc] init];
    testMsg.fromEmail = @"[email protected]";
    testMsg.toEmail = @"[email protected]";
    testMsg.relayHost = @"smtpout.yourserver.net";
    testMsg.requiresAuth = YES;
    testMsg.login = @"[email protected]";
    testMsg.pass = @"yourPassWord";
    testMsg.subject = @"This is the email subject line";
    testMsg.wantsSecure = YES; // smtp.gmail.com doesn't work without TLS!



    // Only do this for self-signed certs!
    // testMsg.validateSSLChain = NO;
    testMsg.delegate = self;

    //email contents
    NSString * bodyMessage = [NSString stringWithFormat:@"This is the body of the email. You can put anything in here that you want."];


    NSDictionary *plainPart = [NSDictionary dictionaryWithObjectsAndKeys:@"text/plain",kSKPSMTPPartContentTypeKey,
                               bodyMessage ,kSKPSMTPPartMessageKey,@"8bit",kSKPSMTPPartContentTransferEncodingKey,nil];

    testMsg.parts = [NSArray arrayWithObjects:plainPart,nil];

    [testMsg send];

}


- (void)messageSent:(SKPSMTPMessage *)message
    {
    [message release];

    //message has been successfully sent . you can notify the user of that and remove the wait overlay
    [self removeWaitOverlay];



    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Message Sent" message:@"Thanks, we have sent your message"
                                                   delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil];
    [alert show];
    [alert release];
}

- (void)messageFailed:(SKPSMTPMessage *)message error:(NSError *)error
{
    [message release];
    [self removeWaitOverlay];

    NSLog(@"delegate - error(%d): %@", [error code], [error localizedDescription]);

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Email Error" message:@"Sending Failed - Unknown Error :-("
                                                   delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil];
    [alert show];
    [alert release];
}



-(void)createWaitOverlay {

    // fade the overlay in
    loadingLabel = @"Sending Test Drive...";
    bgimage = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,320,480)];
    bgimage.image = [UIImage imageNamed:@"waitOverLay.png"];
    [self.view addSubview:bgimage];
    bgimage.alpha = 0;
    [bgimage addSubview:loadingLabel];
    loadingLabel.alpha = 0;


    [UIView beginAnimations: @"Fade In" context:nil];
    [UIView setAnimationDelay:0];
    [UIView setAnimationDuration:.5];
    bgimage.alpha = 1;
    loadingLabel.alpha = 1;
    [UIView commitAnimations];
    [self startSpinner];

    [bgimage release];

}

-(void)removeWaitOverlay {

    //fade the overlay out

    [UIView beginAnimations: @"Fade Out" context:nil];
    [UIView setAnimationDelay:0];
    [UIView setAnimationDuration:.5];
    bgimage.alpha = 0;
    loadingLabel.alpha = 0;
    [UIView commitAnimations];
    [self stopSpinner];


}

-(void)startSpinner {

    spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
    spinner.hidden = FALSE;
    spinner.frame = CGRectMake(137, 160, 50, 50);
    [spinner setHidesWhenStopped:YES];
    [self.view addSubview:spinner];
    [self.view bringSubviewToFront:spinner];
    [spinner startAnimating];
}

-(void)stopSpinner {

    [spinner stopAnimating];
    [spinner removeFromSuperview];
    [spinner release];

}

The final results are shown below. The screen appears to dim a bit (kind of like when an UIAlert is shown). It shows a message saying its being sent, and then "brightens" back up when the message is sent.

Happy Coding!!

enter image description here