MFMessageComposeVIewController 正在解除它的委托而不是它自己
Posted
技术标签:
【中文标题】MFMessageComposeVIewController 正在解除它的委托而不是它自己【英文标题】:MFMessageComposeVIewController is dismissing its delegate instead of itself 【发布时间】:2016-11-02 20:44:38 【问题描述】:我有一个符合 MFMessageComposeViewControllerDelegate 协议的 VC。
我成功地向这个视图控制器展示了以下代码:
- (IBAction)textAction:(id)sender
if(![MFMessageComposeViewController canSendText])
UIAlertView *warningAlert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Your device doesn't support SMS!" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[warningAlert show];
return;
NSString *numberToCallOrText = self.phoneNumber;
NSString *message = @"Test message";
NSArray *recipients = [NSArray arrayWithObject:numberToCallOrText];
MFMessageComposeViewController *messageController = [[MFMessageComposeViewController alloc] init];
messageController.messageComposeDelegate = self;
[messageController setRecipients:recipients];
[messageController setBody:message];
// Present message view controller on screen
[self.view endEditing:YES];
[self presentViewController:messageController animated:YES completion:nil];
另外,我正在像这样处理完成结果:
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult) result
switch (result)
case MessageComposeResultCancelled:
NSLog(@"Canceled");
break;
case MessageComposeResultFailed:
NSLog(@"Failed");
UIAlertView *warningAlert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Failed to send SMS!" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[warningAlert show];
break;
case MessageComposeResultSent:
NSLog(@"sent");
[self.navigationController popViewControllerAnimated:YES];
break;
default:
break;
[controller.view endEditing:YES];
[self.navigationController popViewControllerAnimated:YES];
// [self dismissViewControllerAnimated:YES completion:nil];
// [controller popToViewController:self animated:YES];
// [controller dismissViewControllerAnimated:YES completion:nil];
三个注释掉的行是我尝试过的替代方案。发生的事情是 MFMessageComposeViewController 保留在屏幕上(尽管键盘已关闭),但委托正在从堆栈中弹出。因此,当我再次点击取消时,我得到一个空引用错误。
这很奇怪,因为同样的实现在我的代码中的其他地方也可以使用。唯一的区别是我设置了要初始化的主体。
知道为什么这里会弹出错误的 VC 吗?
谢谢。
编辑 - 损坏的实现是在 UITableViewController 而不是 UIView 控制器上......这可能是导致问题的原因吗?
【问题讨论】:
除了对 TableVC 的编辑之外,一切都(在某一时刻)完全以相同的方式实现。甚至注释掉了setBody
电话。它仍然可以在应用程序的其他地方工作。只是这里取消按钮不起作用。
【参考方案1】:
您正在使用presentViewController:animated:completion:
显示消息编写器。当视图控制器以这种方式呈现时,必须使用dismissViewControllerAnimated:completion:
将其关闭。
但是您使用的是popViewControllerAnimated:
,它告诉导航控制器关闭导航堆栈顶部的任何视图控制器。这不是消息编写器,而是呈现它的视图控制器。
您很接近其中一条注释掉的行。您需要更换:
[self.navigationController popViewControllerAnimated:YES];
与:
[controller dismissViewControllerAnimated:YES completion:nil];
您还需要删除该行:
[self.navigationController popViewControllerAnimated:YES];
消息发送时。不要做任何额外的解雇。
【讨论】:
这是我注释掉的行之一。事实上,我在[self dismissViewControllerAnimated:YES completion:nil];
之后尝试了第二个,这就是我所拥有的另一个实现的工作。这与 presentViewController
配对,是 Apple 在其文档中的内容:developer.apple.com/reference/messageui/…
它也可以在这里工作。您还应该摆脱消息编写器委托方法中对endEditing:
的调用。
这里没有用。我在尝试[self dismissViewController:..
和[controller dismissViewController:...
之后添加了endEditing:
,因为我没有设置断点来查看调用它的tableVC 正在被释放,所以我认为键盘被关闭是在某种程度上吃掉了取消通话。
如果我澄清一下可能会有所帮助,行为是当我第一次点击取消时键盘被关闭(以及我输入消息的文本字段),然后我留下了文本对话和角落的取消按钮。第二次点击取消按钮是导致我崩溃的原因,因为委托不再存在。
你不是很清楚。当您使用[controller dismissViewControllerAnimated:YES completion:nil];
时会发生什么?【参考方案2】:
请看下面的代码希望它对你有用....
-(void) showEmailModalView
if ([MFMailComposeViewController canSendMail])
MFMailComposeViewController* controller
= [[MFMailComposeViewController alloc] init];
controller.mailComposeDelegate = self;
[controller setToRecipients: @[@"dept-em@np.edu.sg"]];
[self presentViewController: controller
animated: YES
completion: nil];
else
UIAlertController* alert = [UIAlertController
alertControllerWithTitle: @"Email not configured"
message: @"Please add/enable an email "
@"account in the phone to send email"
preferredStyle: UIAlertControllerStyleAlert];
UIAlertAction* ok = [UIAlertAction
actionWithTitle: @"Ok"
style: UIAlertActionStyleDefault
handler: nil];
[alert addAction: ok];
[self presentViewController: alert
animated: YES
completion: nil];
- (void) mailComposeController : (MFMailComposeViewController*) controller didFinishWithResult : (MFMailComposeResult) result error :(NSError*) error
switch (result)
case MFMailComposeResultCancelled:
break;
case MFMailComposeResultSaved:
break;
case MFMailComposeResultSent:
break;
case MFMailComposeResultFailed:
break;
default:
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Email" message:@"Sending Failed - Unknown Error :-(" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* ok = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
[alertController addAction:ok];
[self presentViewController:alertController animated:YES completion:nil];
break;
[self dismissViewControllerAnimated:controller completion:nil];
【讨论】:
谢谢,但这或多或少是我已经得到的。我相信这个问题源于我作为表格视图控制器以模态方式呈现的基本 VC。我能够通过首先将一个空白 VC 推到堆栈上来规避这个问题,该堆栈刚刚打开 MFMessageComposeVC 并充当其委托,并在消息完成时自行弹出。【参考方案3】:问题似乎源于从 UITableViewController 而不是 UIViewController 调用 MFMessageComposeViewController。因此,我的解决方案是让表推送另一个视图控制器,其唯一目的是推送 MFMessageComposeViewController,并在 MFMessageComposeViewController 的完成处理程序中自行关闭。
【讨论】:
以上是关于MFMessageComposeVIewController 正在解除它的委托而不是它自己的主要内容,如果未能解决你的问题,请参考以下文章