UIAlertController和UIPopoverController中的通用应用?

时间:2021-09-09 09:25:57

I am working on a universal app for the iPhone 6S / 6S Plus / and iPad form factors. Normally, presenting actionsheets / alertviews on an iPhone-only app is a simple manner. But my application crashes when I attempt to present these on an iPad, returning the following error:

我正在为iPhone 6S / 6S Plus / iPad form factors开发一个通用应用程序。通常,在只支持iphone的应用程序上显示actionsheets / alertviews是一种简单的方式。但当我试图在iPad上显示这些内容时,我的应用程序崩溃了,返回的错误如下:

"Terminating app due to uncaught exception 'NSGenericException', reason: 'Your application has presented a UIAlertController () 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.'"

“由于未捕获的异常'NSGenericException'而终止应用程序,原因是:‘您的应用程序提供了样式为UIAlertControllerStyleActionSheet的UIAlertController()。具有此样式的UIAlertController的modalPresentationStyle是UIModalPresentationPopover。您必须通过警报控制器的popoverPresentationController提供这个弹出窗口的位置信息。您必须提供sourceView和sourceRect或者barButtonItem。如果在显示警报控制器时不知道这个信息,可以在UIPopoverPresentationControllerDelegate方法-prepareForPopoverPresentation.'中提供。

It is my understanding that I must display a popover when the application is running on an iPad instead of a conventional actionsheet. For the sake of context, the action sheet is presented by a button in a custom cell, which is in a tableview.

我的理解是,当应用程序在iPad上运行时,我必须显示弹出窗口,而不是常规的actionsheet。为了上下文的缘故,动作表单是由一个自定义单元格中的按钮提供的,该按钮位于tableview中。

What is the best way to handle UIAlertControllers / Action Sheets / UIPopoverControllers in a universal app?

在通用应用程序中处理UIAlertControllers / Action Sheets / uipopovercontroller的最佳方式是什么?

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    [tableView deselectRowAtIndexPath:indexPath animated:YES];

    NSString *titleToUse = @"";

//    switch (self.openGroup) {
//        case 0:
//            titleToUse = [self.deviceListData[indexPath.row] valueForKey:@"deviceName"];
//            break;
//            
//        case 1:
//            titleToUse = [self.computersData[indexPath.row] valueForKey:@"deviceName"];
//            break;
//            
//        case 2:
//            titleToUse = [self.mobileData[indexPath.row] valueForKey:@"deviceName"];
//            break;
//            
//        case 3:
//            titleToUse = [self.smartData[indexPath.row] valueForKey:@"deviceName"];
//            break;
//            
//        default:
//            break;
//    }

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

    [actionSheet addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {

        // Cancel button tappped.

    }]];

    [actionSheet addAction:[UIAlertAction actionWithTitle:@"Get More Info" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {

        AlertDetailModal *alertDetail = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"alertDetailModal"];

        alertDetail.delegate = self;
        alertDetail.securityLevel = self.securityLevel;

        UINavigationController *modalNavCon = [[UINavigationController alloc] initWithRootViewController:alertDetail];
        [self presentViewController:modalNavCon animated:YES completion:nil];

    }]];

    [actionSheet addAction:[UIAlertAction actionWithTitle:@"Bandwidth Profile" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {

    }]];

    [actionSheet addAction:[UIAlertAction actionWithTitle:@"Alert Settings" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {

    }]];

    [actionSheet addAction:[UIAlertAction actionWithTitle:@"Security Settings" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {

    }]];

    [actionSheet addAction:[UIAlertAction actionWithTitle:@"Unblock Connection" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {

    }]];

    // Present action sheet.
    [self presentViewController:actionSheet animated:YES completion:nil];

}

1 个解决方案

#1


16  

The fact that its universal is irrelevant. You setup the alert controller's popoverPresentationController the same regardless. It will then display properly on all devices.

它的普遍性这一事实无关紧要。无论如何,您都设置了警报控制器的popoverPresentationController。然后它将在所有设备上正确显示。

In this case you should set the sourceView to tableView and sourceRect to the rect for the selected row.

在这种情况下,您应该将sourceView设置为tableView,并将sourceRect设置为所选行的rect。

UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:titleToUse message:nil preferredStyle:UIAlertControllerStyleActionSheet];
actionSheet.popoverPresentationController.sourceView = tableView;
actionSheet.popoverPresentationController.sourceRect = [tableView rectForRowAtIndexPath:indexPath];

#1


16  

The fact that its universal is irrelevant. You setup the alert controller's popoverPresentationController the same regardless. It will then display properly on all devices.

它的普遍性这一事实无关紧要。无论如何,您都设置了警报控制器的popoverPresentationController。然后它将在所有设备上正确显示。

In this case you should set the sourceView to tableView and sourceRect to the rect for the selected row.

在这种情况下,您应该将sourceView设置为tableView,并将sourceRect设置为所选行的rect。

UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:titleToUse message:nil preferredStyle:UIAlertControllerStyleActionSheet];
actionSheet.popoverPresentationController.sourceView = tableView;
actionSheet.popoverPresentationController.sourceRect = [tableView rectForRowAtIndexPath:indexPath];