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

Spo*_*ude 6 objective-c uialertcontroller ios8.1

我将此代码放在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);
                             }
                         }];
Run Code Online (Sandbox Code Playgroud)

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

*** 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];
Run Code Online (Sandbox Code Playgroud)

小智 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];
}
Run Code Online (Sandbox Code Playgroud)


Bra*_*ton 1

这里几乎没有什么宝贵的信息可以继续...

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

我从未使用过这个第三方代码,但快速检查并没有在文档中显示任何明显的“执行此操作”。我最初的建议是在相关视图上实现委托方法,并为其提供所需的内容 - 显示弹出窗口的位置。