Set First Responder in MFMailComposeViewController?
I'm using Apple's MailComposer example application to send email from within my application (OS 3.0 functionality). Is it possible to set the To, Subject, or Body fields as first responder with MFMailComposeViewController?
In other words, the behavior would be: the user presses a button which presents the mail view (presentModalViewController). When the mail view is presented, the cursor is placed in one of the fields and the keyboard opens.
I notice the MFMailComposeViewController documentation says:
"Important: The mail composition interface itself is not customizable and must not be mod开发者_如何学编程ified by your application. In addition, after presenting the interface, your application is not allowed to make further changes to the email content. The user may still edit the content using the interface, but programmatic changes are ignored. Thus, you must set the values of content fields before presenting the interface."
However, I don't care about customizing the interface. I just want to set that firstResponder. Any ideas?
You are able to make these fields become the first responder.
if you add the following method to your class...
//Returns true if the ToAddress field was found any of the sub views and made first responder
//passing in @"MFComposeSubjectView" as the value for field makes the subject become first responder
//passing in @"MFComposeTextContentView" as the value for field makes the body become first responder
//passing in @"RecipientTextField" as the value for field makes the to address field become first responder
- (BOOL) setMFMailFieldAsFirstResponder:(UIView*)view mfMailField:(NSString*)field{
for (UIView *subview in view.subviews) {
NSString *className = [NSString stringWithFormat:@"%@", [subview class]];
if ([className isEqualToString:field])
{
//Found the sub view we need to set as first responder
[subview becomeFirstResponder];
return YES;
}
if ([subview.subviews count] > 0) {
if ([self setMFMailFieldAsFirstResponder:subview mfMailField:field]){
//Field was found and made first responder in a subview
return YES;
}
}
}
//field not found in this view.
return NO;
}
Then, after you present the MFMailComposeViewController, pass the MFMailComposeViewController's view into the function along with the field you want to become first responder.
MFMailComposeViewController *mailComposer = [[MFMailComposeViewController alloc] init];
mailComposer.mailComposeDelegate = self;
/*Set up the mail composer*/
[self presentModalViewController:mailComposer animated:YES];
[self setMFMailFieldAsFirstResponder:mailComposer.view mfMailField:@"RecipientTextField"];
[mailComposer release];
In iOS 6, it is no longer possible to set first responder on any of the text fields AFAICT. Navigating the view hierarchy eventually reveals a UIRemoteView and the subviews within here are obfuscated away.
You can try just calling becomeFirstResponder on the controller itself. If that doesn't work, you can try in the debugger getting the list of subviews of the mail compose view until you find a familiar textfield or textview which you can then code specifically to set the responder status in code, which might look something like this (i don't know if this will work but it's an example):
[[[[mailcomposer.view.subviews objectAtIndex:3] subviews] objectAtIndex:2] becomeFirstResponder]
I like to simplify the code and make it easy to understand.
Just put the follow code after:
[self presentModalViewController:mailComposer animated:YES];
for (UIView *subview in mailComposer.view.subviews) {
NSString *className = [NSString stringWithFormat:@"%@", [subview class]];
//NSLog(@"%@", className); // list the views - Use this to find another view
//The view I want to set as first responder: "_MFMailRecipientTextField"
if ([className isEqualToString:@"_MFMailRecipientTextField"]){
[subview becomeFirstResponder];
break; // Stop search.
}
}
精彩评论