使用iOS 8在iPad上正确呈现UIAlertController

在iOS 8.0中,Apple引入了UIAlertController来replaceUIActionSheet 。 不幸的是,苹果没有添加任何关于如何呈现的信息。 我在hayaGeek的博客上发现了一个关于它的条目 ,但是它似乎在iPad上不起作用。 这个看法是完全错误的:

放错了地方: 错位的图像

正确: 在这里输入图像说明

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

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

有另一种方式来添加它的iPad? 还是苹果公司只是忘了iPad,还是没有实施呢?

您可以通过使用UIPopoverPresentationController从popup窗口提供UIPopoverPresentationController

在Obj-C中:

 UIViewController *self; // code assumes you're in a view controller UIButton *button; // the button you want to show the popup sheet from UIAlertController *alertController; UIAlertAction *destroyAction; UIAlertAction *otherAction; alertController = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet]; destroyAction = [UIAlertAction actionWithTitle:@"Remove All Data" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) { // do destructive stuff here }]; otherAction = [UIAlertAction actionWithTitle:@"Blah" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { // do something here }]; // note: you can control the order buttons are shown, unlike UIActionSheet [alertController addAction:destroyAction]; [alertController addAction:otherAction]; [alertController setModalPresentationStyle:UIModalPresentationPopover]; UIPopoverPresentationController *popPresenter = [alertController popoverPresentationController]; popPresenter.sourceView = button; popPresenter.sourceRect = button.bounds; [self presentViewController:alertController animated:YES completion:nil]; 

在iPad上,警报将显示为使用新的UIPopoverPresentationController的popup窗口 ,它要求您使用sourceView和sourceRect或barButtonItem指定popup窗口的显示的锚点

  • 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]; 

在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) } 

如果您没有设置演示者,则会在-[UIPopoverPresentationController presentationTransitionWillBegin] iPad上出现exception,并显示以下消息:

致命exception:NSGenericException您的应用程序提供了样式为UIAlertControllerStyleActionSheet的UIAlertController(<UIAlertController:0x17858a00>)。 具有此样式的UIAlertController的modalPresentationStyle是UIModalPresentationPopover。 您必须通过警报控制器的popoverPresentationController为此popup窗口提供位置信息。 您必须提供sourceView和sourceRect或barButtonItem。 如果在显示警报控制器时不知道此信息,则可以在UIPopoverPresentationControllerDelegate方法-prepareForPopoverPresentation中提供此信息。

这是一个快速解决scheme:

 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 3.0和更高版本

  let actionSheetController: UIAlertController = UIAlertController(title: "SomeTitle", message: nil, preferredStyle: .actionSheet) let editAction: UIAlertAction = UIAlertAction(title: "Edit Details", style: .default) { action -> Void in print("Edit Details") } let deleteAction: UIAlertAction = UIAlertAction(title: "Delete Item", style: .default) { action -> Void in print("Delete Item") } let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .cancel) { action -> Void in } actionSheetController.addAction(editAction) actionSheetController.addAction(deleteAction) actionSheetController.addAction(cancelAction) // present(actionSheetController, animated: true, completion: nil) // doesn't work for iPad actionSheetController.popoverPresentationController?.sourceView = yourSourceViewName // works for both iPhone & iPad present(actionSheetController, animated: true) { print("option menu presented") }