【问题标题】:Action sheet doesn't display when the MFMailComposeViewController's cancel button is tapped点击 MFMailComposeViewController 的取消按钮时,操作表不显示
【发布时间】:2010-11-25 08:11:26
【问题描述】:

我正在尝试将MFMailComposeViewController 合并到我的应用程序中。当我以模态方式呈现它时,发送按钮可以正常工作并发送电子邮件,这意味着在这种情况下发送给代表的结果是正确的。

而当我点击取消按钮时,它会挂断应用程序。日志也没有显示任何错误,只是屏幕变暗,一切都被禁用。显然,结果没有传递给委托(我通过日志检查了它)。看来

(void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error

永远不会在按下取消按钮时调用。可能这就是未显示操作表(保存草稿取消删除草稿)的原因,因此应用程序就挂在那里了。

我正在使用来自 Apple 示例应用程序 (MailComposer) 的确切代码,它在那里完美运行,但不知何故我的失败了。 :(

如果有人遇到过同样的问题并成功解决,请帮助我。

我的代码:

  -(IBAction)emailButtonPressed:(id)sender{

           Class mailClass = (NSClassFromString(@"MFMailComposeViewController"));
       if (mailClass != nil)
          {

          if ([mailClass canSendMail])
            {
              [self displayComposerSheet];
            }
          else
            {
              [self launchMailAppOnDevice];
            }
          }
        else
          {
            [self launchMailAppOnDevice];
          }


}


#pragma mark -
#pragma mark Compose Mail


-(void)displayComposerSheet 
{
    MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
    picker.mailComposeDelegate = self;

    [picker setSubject:@"Ilusiones"];


    // Set up recipients
     NSArray *toRecipients = [NSArray arrayWithObject:@"anam@semanticnotion.com"]; 

     [picker setToRecipients:toRecipients];
     // Attach a screenshot to the email      
     UIGraphicsBeginImageContext(self.view.bounds.size);
     [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
     UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
     UIGraphicsEndImageContext();

         NSData *myData = UIImagePNGRepresentation(viewImage);
     [picker addAttachmentData:myData mimeType:@"image/png" fileName:@"viewImage"];



     // Fill out the email body text
     NSString *emailBody = @"";
     [picker setMessageBody:emailBody isHTML:NO];

     [self presentModalViewController:picker animated:YES];
         [picker release];

 }

 - (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error 
 {  

  switch (result)
  {
case MFMailComposeResultCancelled:
    NSLog(@"Result: canceled");
    break;
case MFMailComposeResultSaved:
    NSLog(@"Result: saved");
    break;
case MFMailComposeResultSent:
    NSLog( @"Result: sent");
    break;
case MFMailComposeResultFailed:
    NSLog( @"Result: failed");
    break;
default:
    NSLog(@"Result: not sent");
    break;
 }
 [self dismissModalViewControllerAnimated:YES];
}


#pragma mark -
#pragma mark Workaround


-(void)launchMailAppOnDevice
{
NSString *recipients = @"mailto:anam@semanticnotion.com.com?cc=second@example.com,third@example.com&subject=illusions!";
NSString *body = @"&body=xyz";

NSString *email = [NSString stringWithFormat:@"%@%@", recipients, body];
email = [email stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:email]];
}

【问题讨论】:

    标签: iphone objective-c ios4


    【解决方案1】:

    方法

    (void)mailComposeController:(MFMailComposeViewController*)controller
            didFinishWithResult:(MFMailComposeResult)result
                          error:(NSError*)error
    

    永远不会被调用,因为您在取消后没有按任何 UIActionSheet 按钮,因为它不会显示在屏幕上。

    发生这种情况的原因是UIActionSheet 出现在屏幕外。如果您检查调试日志,您可能会看到一条消息,说 Prepresenting action sheet 被其 superview 剪切。某些控件可能无法响应触摸。 在 iPhone 上尝试使用 -[UIActionSheet showFromTabBar:]-[UIActionSheet showFromToolbar:] 而不是 -[UIActionSheet showInView:]。"

    这就是为什么你看到你的视图变暗了,但没有出现UIActionSheet

    就我而言,问题在于我的应用程序是通用的,但由于某种原因,只有一个MainWindow.xib,而且它比 iPhone 的屏幕尺寸大(实际上是 iPad 的屏幕尺寸)。

    解决方案是创建另一个具有正确尺寸的MainWindow-iPhone.xib,并更改名为Main nib file base (iPad)Main nib file base (iPhone)的Info.plist条目 以便它们指向正确的文件。问题解决了!

    希望对你有帮助。

    【讨论】:

      【解决方案2】:

      我遇到了同样的问题,注释掉了'[picker release];',效果很好!解释?我没有。

      【讨论】:

        【解决方案3】:

        Msoler 说得对,操作表显示在屏幕外。 MFMailComposeViewController 在 x:y 0:0 处显示操作表,因此您必须确保调用控制器框架位于 0:0。当我尝试从嵌入在滚动视图中的视图中显示 MFMailComposeViewController 时,我遇到了类似的问题。

        【讨论】:

          【解决方案4】:

          我已经实现了相同的代码。它工作得很好。单击删除草稿按钮时,将调用didFinishWithResult 方法并取消邮件。

          【讨论】:

          • 我知道,它在我的应用程序的其他视图上也能正常工作。但是在这个视图中,actionsheet 永远不会出现!是不是因为我的视图已经是模态视图了?
          • 那么你想要邮件撰写者的观点是什么
          【解决方案5】:

          请务必使用正确的方法,

           -(void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
          

          我实现了一些从未调用过的类似方法。我不知道我到底有什么,但编译器没有给我警告或错误消息。

          【讨论】:

            【解决方案6】:

            以防万一其他人犯了和我一样的错误...我在我的 Swift 代码中实现了 mailComposeController:didFinishWithResult:error: 方法。它工作了一段时间,但经过几次重构后,我注意到它突然不再被调用。最终我注意到该方法在我的代码中采用了这种形式:

            private func mailComposeController(controller: MFMailComposeViewController!, didFinishWithResult result: MFMailComposeResult, error: NSError!) {
                presentingViewController?.dismissViewControllerAnimated(true, completion: nil)
            } 
            

            所以,正如您所看到的,我有点过于渴望将我的方法私有化:由于该方法在 MFMailComposeViewControllerDelegate 中标记为 @optional,因此您不必实现它。虽然我实际上已经实现了它,但那里的 private 修饰符隐藏了实现 - 因此,从文件外部看来,该方法实际上根本没有实现!但是,由于该方法是可选的,因此编译器没有抱怨...

            总结:不要使用修饰符private 标记可选委托。

            自从学习 Swift 以来,我一直想知道为什么不再有可选方法 - 现在我可能已经理解了 ;-)。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-04-26
              • 2016-12-22
              • 1970-01-01
              • 1970-01-01
              • 2015-07-10
              相关资源
              最近更新 更多