在iOS 8.0中,苹果引入了UIAlertController来取代UIActionSheet。不幸的是,苹果没有提供任何关于如何展示的信息。我在hayaGeek的博客上找到了一个关于它的条目,然而,它似乎不能在iPad上运行。这种观点是完全错误的:

错误的:

正确的:

我使用以下代码在界面上显示它:

    let alert = UIAlertController()
    // setting buttons
    self.presentModalViewController(alert, animated: true)

是否有其他方法添加到iPad上?或者苹果只是忘记了iPad,或者还没有推出iPad ?


当前回答

在iPad上,警报将使用新的UIPopoverPresentationController以弹出窗口的形式显示,它要求你为弹出窗口的显示指定一个锚点,使用:

或者barButtonItem 或者一个sourceView和sourceRect

为了指定锚点,你需要获得UIAlertController的UIPopoverPresentationController的引用,并设置其中一个属性如下:

alertController.popoverPresentationController.barButtonItem = button;

示例代码:

UIAlertAction *actionDelete = nil;
UIAlertAction *actionCancel = nil;

// create action sheet
UIAlertController *alertController = [UIAlertController
                                      alertControllerWithTitle:actionTitle message:nil
                                      preferredStyle:UIAlertControllerStyleActionSheet];

// Delete Button
actionDelete = [UIAlertAction
                actionWithTitle:NSLocalizedString(@"IDS_LABEL_DELETE", nil)
                style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) {
                    
                    // Delete
                    // [self deleteFileAtCurrentIndexPath];
                }];

// Cancel Button
actionCancel = [UIAlertAction
                actionWithTitle:NSLocalizedString(@"IDS_LABEL_CANCEL", nil)
                style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
                    // cancel
                    // Cancel code
                }];

// Add Cancel action
[alertController addAction:actionCancel];
[alertController addAction:actionDelete];

// show action sheet
alertController.popoverPresentationController.barButtonItem = button;
alertController.popoverPresentationController.sourceView = self.view;

[self presentViewController:alertController animated:YES
                 completion:nil];

其他回答

它将同时适用于iphone和ipad

func showImagePicker() {
    var alertStyle = UIAlertController.Style.actionSheet
    if (UIDevice.current.userInterfaceIdiom == .pad) {
      alertStyle = UIAlertController.Style.alert
    }
    let alert = UIAlertController(title: "", message: "Upload Attachment", preferredStyle: alertStyle)
    alert.addAction(UIAlertAction(title: "Choose from gallery", style: .default , handler:{ (UIAlertAction) in
        self.pickPhoto(sourceType: .photoLibrary)
    }))
    alert.addAction(UIAlertAction(title: "Take Photo", style: .default, handler:{ (UIAlertAction) in
        self.pickPhoto(sourceType: .camera)
    }))
    alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler:{ (UIAlertAction) in
    }))
    present(alert, animated: true, completion: nil)
}

斯威夫特4.2 你可以像这样使用condition:

let alert = UIAlertController(title: nil, message: nil, preferredStyle: UIDevice.current.userInterfaceIdiom == .pad ? .alert : .actionSheet)

如果您的代码库同时支持iPhone和iPad设备,请考虑以下内容

在以下情况下定期使用present(_ viewcontrollertoppresent:animated:completion:)

呈现一个preferredStyle为.alert的UIAlertController 用.modalPresentationStyle表示一个UIViewController: .overFullScreen .formSheet .automatic未指定modalPresentationStyle时的默认值 .currentContext .fullScreen .custom .overCurrentContext

在呈现前配置popoverPresentationController的sourceRect和sourceView:

Presenting a UIAlertController with preferredStyle of .actionSheet Presenting a UIViewController with .modalPresentationStyle of: .popover .none This will crash on both iPhone and iPads with the error "The specified modal presentation style doesn't have a corresponding presentation controller." Presenting a UIActivityViewController (Based on https://developer.apple.com/documentation/uikit/uiactivityviewcontroller ; "On iPad, you must present the view controller in a popover. On iPhone and iPod touch, you must present it modally.")

下面是一个配置popoverPresentationController的例子

if let popoverController = popoverPresentationController {
  popoverController.sourceView = view
  popoverController.sourceRect = CGRect(x: view.bounds.maxX, y: 40, width: 0, height: 0)
}

如果你发现这里没有列出的其他案例,请告诉我!

这里有一个快速的解决方案:

NSString *text = self.contentTextView.text;
NSArray *items = @[text];

UIActivityViewController *activity = [[UIActivityViewController alloc]
                                      initWithActivityItems:items
                                      applicationActivities:nil];

activity.excludedActivityTypes = @[UIActivityTypePostToWeibo];

if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
    //activity.popoverPresentationController.sourceView = shareButtonBarItem;

    activity.popoverPresentationController.barButtonItem = shareButtonBarItem;

    [self presentViewController:activity animated:YES completion:nil];

}
[self presentViewController:activity animated:YES completion:nil];

在Swift 2中,你想要在iPhone和iPad上正确地显示它:

func confirmAndDelete(sender: AnyObject) {
    guard let button = sender as? UIView else {
        return
    }

    let alert = UIAlertController(title: NSLocalizedString("Delete Contact?", comment: ""), message: NSLocalizedString("This action will delete all downloaded audio files.", comment: ""), preferredStyle: .ActionSheet)
    alert.modalPresentationStyle = .Popover

    let action = UIAlertAction(title: NSLocalizedString("Delete", comment: ""), style: .Destructive) { action in
        EarPlaySDK.deleteAllResources()
    }
    let cancel = UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .Cancel) { action in

    }
    alert.addAction(cancel)
    alert.addAction(action)

    if let presenter = alert.popoverPresentationController {
        presenter.sourceView = button
        presenter.sourceRect = button.bounds
    }
    presentViewController(alert, animated: true, completion: nil)
}

如果你不设置演示器,你将在iPad上出现一个异常-[UIPopoverPresentationController presentationTransitionWillBegin],并显示以下消息:

Fatal Exception: NSGenericException Your application has presented a UIAlertController (<UIAlertController: 0x17858a00>) 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.