Presentar un UIAlertController correctamente en un iPad con iOS 8

Con iOS 8.0, Apple introdujo UIAlertController para reemplazar a UIActionSheet . Desafortunadamente, Apple no agregó ninguna información sobre cómo presentarlo. Encontré una entrada al respecto en el blog de hayaGeek, sin embargo, parece que no funciona en el iPad. La vista está totalmente fuera de lugar:

Fuera de lugar: Imagen perdida

Correcto: enter image description here

Utilizo el siguiente código para mostrarlo en la interfaz:

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

¿Hay alguna otra forma de agregarlo para iPad? ¿O acaso Apple simplemente olvidó el iPad, o no lo implementó?

Puede presentar un UIAlertController desde un popover usando UIPopoverPresentationController .

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

En el iPad, la alerta se mostrará como un popover usando el nuevo UIPopoverPresentationController , requiere que especifique un punto de anclaje para la presentación del popover usando un sourceView y sourceRect o un barButtonItem

  • barButtonItem
  • sourceView
  • fuenteRect

Para especificar el punto de anclaje, deberá obtener una referencia al UIPopoverPresentationController de UIAlertController y establecer una de las propiedades de la siguiente manera:

 alertController.popoverPresentationController.barButtonItem = button; 

Código de muestra:

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

En Swift 2, quiere hacer algo como esto para mostrarlo correctamente en iPhone y 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) } 

Si no configura el presentador, terminará con una excepción en iPad en -[UIPopoverPresentationController presentationTransitionWillBegin] con el siguiente mensaje:

Fatal Exception: NSGenericException Su aplicación presentó un UIAlertController () del estilo UIAlertControllerStyleActionSheet. El modalPresentationStyle de un UIAlertController con este estilo es UIModalPresentationPopover. Debe proporcionar información de ubicación para este popover a través del controlador de alerta popoverPresentationController. Debe proporcionar un sourceView y sourceRect o un barButtonItem. Si no se conoce esta información cuando presenta el controlador de alertas, puede proporcionarlo en el método UIPopoverPresentationControllerDelegate -prepareForPopoverPresentation.

Actualización para Swift 3.0 y superior

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

Aquí hay una solución rápida:

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

Actualización 2018

Acabo de rechazar una aplicación por este motivo y una resolución muy rápida fue simplemente cambiar de usar una hoja de acción a una alerta.

Funcionó con encanto y superó a los evaluadores de la tienda de aplicaciones.

Puede que no sea una respuesta adecuada para todos, pero espero que esto ayude a algunos de ustedes a salir de un aprieto rápidamente.

Intereting Posts