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.
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 = @\"youremail@email.com\";
testMsg.toEmail = @\"targetemailaddress@email.com\";
testMsg.relayHost = @\"smtpout.yourserver.net\";
testMsg.requiresAuth = YES;
testMsg.login = @\"yourusername@email.com\";
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!!