如何使用UIAlertController修复运行时错误

时间:2014-12-29 00:03:03

标签: objective-c ios8.1 uialertcontroller

我将此代码放在UIVIewController(XCode 6.1,iOS 8.1.1)中:

[UIAlertController showActionSheetInViewController:self
                         withTitle:@"Test Action Sheet"
                         message:NSLocalizedString(@"Are you sure you want to delete ALL appointments?",nil)
                         cancelButtonTitle:@"Cancel"
                         destructiveButtonTitle:@"Yes"
                         otherButtonTitles:@[@"No"]  //  same as Cancel
                         tapBlock:^(UIAlertController *controller, UIAlertAction *action, NSInteger buttonIndex){
                              if (buttonIndex == UIAlertControllerBlocksCancelButtonIndex) {
                                 NSLog(@"Cancel Tapped");
                             } else if (buttonIndex == UIAlertControllerBlocksDestructiveButtonIndex) {
                                 NSLog(@"Delete Tapped");
                             } else if (buttonIndex >= UIAlertControllerBlocksFirstOtherButtonIndex) {
                                 NSLog(@"Other Action Index %ld", (long)buttonIndex - UIAlertControllerBlocksFirstOtherButtonIndex);
                             }
                         }];

当我运行它时,我得到这个运行时错误:

  

*** Terminating app due to uncaught exception 'NSGenericException', reason: 'Your application has presented a UIAlertController (<UIAlertController: 0x7fdfe3324f00>) of style UIAlertControllerStyleActionSheet. The modalPresentationStyle of a UIAlertController with this style is UIModalPresentationPopover. You must provide location information for this popover through the alert controller's popoverPresentationController. You must provide either a sourceView and sourceRect or a barButtonItem. If this information is not known when you present the alert controller, you may provide it in the UIPopoverPresentationControllerDelegate method -prepareForPopoverPresentation.'

我需要做些什么来完成这项工作? (我看过SO和谷歌并没有找到具体的内容)。我很感激我能得到的任何帮助...

更新 我在没有第三方代码的情况下重写了它;添加了这段代码,现在可以了!

    UIAlertController * view=   [UIAlertController
                             alertControllerWithTitle:@"My Title"
                             message:@"Select your Choice"
                             preferredStyle:UIAlertControllerStyleActionSheet];

UIAlertAction* ok = [UIAlertAction
                     actionWithTitle:@"OK"
                     style:UIAlertActionStyleDefault
                     handler:^(UIAlertAction * action)
                     {
                         //Do some thing here
                         [view dismissViewControllerAnimated:YES completion:nil];

                     }];
UIAlertAction* cancel = [UIAlertAction
                         actionWithTitle:@"Cancel"
                         style:UIAlertActionStyleDefault
                         handler:^(UIAlertAction * action)
                         {
                             [view dismissViewControllerAnimated:YES completion:nil];

                         }];


[view addAction:ok];
[view addAction:cancel];

view.popoverPresentationController.sourceView = self.view;
view.popoverPresentationController.sourceRect = CGRectMake(self.view.bounds.size.width / 2.0, self.view.bounds.size.height / 2.0, 1.0, 1.0);
[self presentViewController: view animated:YES completion:nil];

2 个答案:

答案 0 :(得分:7)

您收到的错误消息是因为您在iPad上运行iPhone代码而出现的。要在iPad上使用,您必须设置alertController的popoverPresentationController。也可以在没有草率尺寸计算的情况下生成源矩形。下面是一个完整的方法,显示了在按下按钮时如何遇到代码。按照您想要的方式设置AlertController后,您将获得其popoverPresentationController并将其设置为与iPad一起使用。在下面的方法中,按下的按钮是发件人。所以我们将发送者强制转换回该按钮,然后使用按钮设置矩形。没有杂乱的维度需要计算。现在,如果你在iPad上运行代码,弹出框将不会显示取消按钮(它确实出现在iPhone上)。那是设计上的。如果您查看Apple UIPopoverController文档,您会看到通过点击它来取消弹出窗口。

- (IBAction)showImagePickerButtonTapped:(id)sender;
{
    BOOL isCameraAvailable = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera];
    BOOL isPhotoLibraryAvailable = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary];

    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];

    [alertController addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]];

    if (isCameraAvailable) {
        [alertController addAction:[UIAlertAction actionWithTitle:@"Camera" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
            [self _showImagePickerWithSourceType:UIImagePickerControllerSourceTypeCamera];
        }]];
    }

    if (isPhotoLibraryAvailable) {
        [alertController addAction:[UIAlertAction actionWithTitle:@"Photo Library" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
            [self _showImagePickerWithSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
        }]];
    }

    // The following lines are needed for use with the iPad.
    UIPopoverPresentationController *alertPopoverPresentationController = alertController.popoverPresentationController;
    UIButton *imagePickerButton = (UIButton*)sender;
    alertPopoverPresentationController.sourceRect = imagePickerButton.frame;
    alertPopoverPresentationController.sourceView = self.view;

    [self showDetailViewController:alertController sender:sender];
}

答案 1 :(得分:1)

这里有很少的信息......

看起来你正在使用https://github.com/ryanmaxwell/UIAlertController-Blocks,而不是标准的UIAlertController,在这种情况下,异常表示您正在使用的代码版本尚未涵盖的更改或需要额外工作的用例对你而言。

我从未使用过这个第三方代码,但快速检查并未在文档中显示任何明显的“执行此操作”。我最初的建议是在有问题的视图上实现委托方法并给它想要的东西 - 呈现弹出窗口的位置。