Представление UIAlertController правильно на iPad с помощью iOS 8
В iOS 8.0 Apple представила UIAlertController для замены UIActionSheet. К сожалению, Apple не добавила никакой информации о том, как ее представить. Я нашел запись об этом в блоге hayaGeek, однако он, похоже, не работает на iPad. Вид полностью неуместен:
Misplaced:
![Misplaced image]()
Правильно:
![enter image description here]()
Я использую следующий код, чтобы показать его на интерфейсе:
let alert = UIAlertController()
// setting buttons
self.presentModalViewController(alert, animated: true)
Есть ли другой способ добавить его для iPad? Или Apple просто забыла iPad или еще не реализована?
Ответы
Ответ 1
Вы можете представить UIAlertController
из всплывающего окна, используя 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];
Редактирование для 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
}
Ответ 2
В iPad предупреждение будет отображаться как popover с использованием нового UIPopoverPresentationController, для этого требуется указать опорную точку для представления popover, используя либо 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];
Ответ 3
В 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 Ваша заявка представила UIAlertController (< UIAlertController: 0x17858a00 > ) стиля UIAlertControllerStyleActionSheet. ModalPresentationStyle UIAlertController с этим стилем - UIModalPresentationPopover. Вы должны предоставить информацию о местоположении для этого popover через контроллер предупреждения popoverPresentationController. Вы должны указать либо sourceView, и sourceRect, либо barButtonItem. Если эта информация неизвестна при представлении контроллера предупреждений, вы можете предоставить ее в методе UIPopoverPresentationControllerDelegate -prepareForPopoverPresentation.
Ответ 4
Обновление для 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")
}
Ответ 5
2018 Обновление
Я просто отклонил приложение по этой причине, и очень быстрое решение состояло в том, чтобы просто перейти от использования листа действий к предупреждению.
Сработал шарм и прошел тестеры App Store просто отлично.
Может быть, не всем подходит ответ, но я надеюсь, что это поможет некоторым из вас быстро выйти из-под маринада.
Ответ 6
Здесь быстрое решение:
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];
Ответ 7
Свифт 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)
Ответ 8
if let popoverController = alertController.popoverPresentationController {
popoverController.barButtonItem = navigationItem.rightBarButtonItem
}
для меня мне просто нужно добавить эту строку
Ответ 9
if let popoverController = optionMenu.popoverPresentationController {
popoverController.sourceView = self.view
popoverController.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
popoverController.permittedArrowDirections = []
}
просто добавьте приведенный выше код, прежде чем представить свой uiactionsheet
Ответ 10
Вы найдете ответ здесь: https://medium.com/@nickmeehan/actionsheet-popover-on-ipad-in-swift-5768dfa82094