如何使用UIAlertController解决运行时错误

6

我有一段代码放在一个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);
                             }
                         }];

当我运行它时,我得到了这个运行时错误:
未捕获的异常 'NSGenericException',原因是:'您的应用程序已经呈现了一个UIAlertController (),其样式为UIAlertControllerStyleActionSheet。具有此样式的UIAlertController的modalPresentationStyle是UIModalPresentationPopover。您必须通过警报控制器的popoverPresentationController提供此弹出窗口的位置信息。您必须提供sourceView和sourceRect或barButtonItem之一。如果在呈现警报控制器时不知道这些信息,则可以在UIPopoverPresentationControllerDelegate方法-prepareForPopoverPresentation中提供它们。'
我需要做什么才能使它工作?(我已经查看了SO和Google,没有找到具体的解决办法)。非常感谢您的帮助...
更新: 我重新编写了它而没有使用第三方代码;添加了这段代码,现在它可以工作了!
    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个回答

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

这里可供参考的信息非常少...

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

我从未使用过这个第三方代码,但快速检查文档并没有显示任何明显的“做这个”的建议。我的初步建议是在相关视图上实现委托方法,并给它想要的东西 - 弹出窗口显示的位置。


我已经更新了问题并更正了代码。感谢你的帮助,Brad!我很感激。 - SpokaneDude

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接