在iOS 8.0中,Apple引入了UIAlertController来取代UIActionSheet.不幸的是,Apple没有添加任何有关如何呈现它的信息.我在hayaGeek的博客上找到了一个关于它的条目,然而,它似乎不适用于iPad.视图完全错位:
放错了地方:
正确:
我使用以下代码在界面上显示它:
let alert = UIAlertController() // setting buttons self.presentModalViewController(alert, animated: true)
还有其他方法可以将它添加到iPad吗?或者苹果只是忘了iPad,还是没有实现?
您可以UIAlertController
使用弹出来自弹出窗口UIPopoverPresentationController
.
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];
编辑Swift 4.2,虽然有很多博客可用,但它可以节省您的时间去搜索它们.
if let popoverController = yourAlert.popoverPresentationController { popoverController.sourceView = self.view //to set the source of your alert popoverController.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0) // you can set this as per your requirement. popoverController.permittedArrowDirections = [] //to hide the arrow of any particular direction }
更新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") }
这是一个快速的解决方案:
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]
消息,并显示以下消息:
致命异常:NSGenericException您的应用程序提供了样式UIAlertControllerStyleActionSheet的UIAlertController(<UIAlertController:0x17858a00>).具有此样式的UIAlertController的modalPresentationStyle是UIModalPresentationPopover.您必须通过警报控制器的popoverPresentationController为此弹出窗口提供位置信息.您必须提供sourceView和sourceRect或barButtonItem.如果在显示警报控制器时未知此信息,则可以在UIPopoverPresentationControllerDelegate方法-prepareForPopoverPresentation中提供该信息.
在iPad上,警报将使用新的UIPopoverPresentationController显示为弹出窗口,它要求您使用sourceView和sourceRect或barButtonItem为弹出窗口的表示指定锚点
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];
2018年更新
由于这个原因我只是拒绝了一个应用程序,并且一个非常快速的解决方案只是从使用操作表变为警报.
工作了一个魅力,并通过App Store测试员就好了.
对于每个人来说可能不是一个合适的答案,但我希望这可以帮助你们中的一些人迅速摆脱困境.
快速4及以上
我创建了一个扩展
extension UIViewController { public func addActionSheetForiPad(actionSheet: UIAlertController) { if let popoverPresentationController = actionSheet.popoverPresentationController { popoverPresentationController.sourceView = self.view popoverPresentationController.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0) popoverPresentationController.permittedArrowDirections = [] } } }
如何使用:
let actionSheetVC = UIAlertController(title: "Title", message: nil, preferredStyle: .actionSheet) addActionSheetForIpad(actionSheet: actionSheetVC) present(actionSheetVC, animated: true, completion: nil)