ios objective-c uipopovercontroller deprecated

ios - ¿Cómo puedo corregir la advertencia "UIPopoverController está en desuso"?



objective-c deprecated (4)

Estoy usando este código:

mediaLibraryPopover = [[UIPopoverController alloc] initWithContentViewController:avc]; [self.mediaLibraryPopover presentPopoverFromRect:[theButton bounds] inView:theButton permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

Y estoy recibiendo esta advertencia en Xcode 7:

UIPopoverController está en desuso, primero en desuso en iOS 9.0 - UIPopoverController está en desuso. Los popovers ahora se implementan como presentaciones de UIViewController. Use un estilo de presentación modal de UIModalPresentationPopover y UIPopoverPresentationController.


Apple tiene la manera oficial de presentar y configurar popovers para iOS8 aquí: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIPopoverPresentationController_class/index.html

Si bien es similar a la respuesta de @MadhunMP, vale la pena señalar el párrafo:

Configuración del controlador de presentación presentViewController:animated:completion: después de llamar a presentViewController:animated:completion: puede parecer contraintuitivo, pero UIKit no crea un controlador de presentación hasta después de que inicie una presentación. Además, UIKit debe esperar hasta el próximo ciclo de actualización para mostrar el contenido nuevo en pantalla de todos modos. Ese retraso le da tiempo para configurar el controlador de presentación para su ventana emergente.

La configuración y la respuesta a los eventos también se pueden realizar a través de un delegado si lo desea ( https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIPopoverPresentationControllerDelegate_protocol/index.html ).

Un ejemplo, dejando de lado el uso del delegado:

// Present the controller using the popover style. controller.modalPresentationStyle = UIModalPresentationPopover; [self presentViewController:controller animated:YES completion:nil]; // Popover presentation controller was created when presenting; now configure it. UIPopoverPresentationController *presentationController = [controller popoverPresentationController]; presentationController.permittedArrowDirections = UIPopoverArrowDirectionLeft; presentationController.sourceView = containerFrameOfReferenceView; // arrow points out of the rect specified here presentationController.sourceRect = childOfContainerView.frame;

Pero también querrás descartar esto. Para hacerlo sin usar un delegado, su controlador de presentación puede simplemente llamar:

[self dismissViewControllerAnimated:YES completion:nil];

¿Pero qué sucede si giro mi dispositivo y la ventana emergente no apunta al área correcta? Su controlador de presentación puede manejarlo:

// Respond to rotations or split screen changes - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator { [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; [coordinator animateAlongsideTransition:nil completion:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) { // Fix up popover placement if necessary, after the transition. if (self.presentedViewController) { UIPopoverPresentationController *presentationController = [self.presentedViewController popoverPresentationController]; presentationController.sourceView = containerFrameOfReferenceView; presentationController.sourceRect = childOfContainerView.frame; } }]; }


EDITAR: Sobre los votos a la baja. Primero una historia divertida y relevante:

http://www.folklore.org/StoryView.py?story=Negative_2000_Lines_Of_Code.txt

Publiqué la respuesta a continuación para ayudar a los programadores que podrían haberse quedado atascados en la mentalidad de que el iPad / iPhone todavía necesitaba rutas de ejecución separadas al presentar una interfaz de usuario del selector de medios. En el momento de mi publicación original, esto no estaba claro en las otras respuestas. Esta ruta de solución simplificó mi código y el futuro mantenimiento de mi aplicación. Creo que a otros les puede resultar útil esta perspectiva porque a veces eliminar una línea correcta de código puede ser una buena solución.

Fin de edición.

Si ya tiene un programa en funcionamiento y solo desea deshacerse de la advertencia de depreciación, esto podría funcionar para usted.

En mi código, y en mi opinión, Popovers se introdujeron para el iPad y son específicos de iPad. Apple parece haber cambiado eso. Entonces, si ya tienes un programa de trabajo que usa algo como esto:

if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) // use popovers else // don''t use popovers

lo que puede hacer es simplemente deshacerse del código específico del iPad (que es probablemente el código que usa Popovers) y hacer que su programa ejecute las mismas instrucciones para iPhone y iPad. Esto funcionó para mí.


Si se desea directamente desde Button Action, este código puede ser usado

SecondViewController *destinationViewController = (SecondViewController *)[self.storyboard instantiateViewControllerWithIdentifier:@"second"]; destinationViewController.modalPresentationStyle = UIModalPresentationPopover; destinationViewController.popoverPresentationController.sourceView = self.customButton; // Set the correct sourceRect given the sender''s bounds destinationViewController.popoverPresentationController.sourceRect = ((UIView *)sender).bounds; [self presentViewController:destinationViewController animated:YES completion:nil];


Ya no necesita UIPopoverController para presentar un controlador de vista. En su lugar, puede configurar el controlador modalPresentationStyle of view en UIModalPresentationPopover .

Puedes usar el siguiente código para eso:

avc.modalPresentationStyle = UIModalPresentationPopover; avc.popoverPresentationController.sourceView = theButton; [self presentViewController:avc animated:YES completion:nil];

UIModalPresentationPopover

En un entorno horizontal regular, un estilo de presentación donde el contenido se muestra en una vista emergente. El contenido de fondo se atenúa y los toques fuera de la ventana emergente hacen que la ventana emergente se cierre. Si no desea que las pulsaciones descarten el popover, puede asignar una o más vistas a la propiedad passthroughViews del objeto UIPopoverPresentationController asociado, que puede obtener de la propiedad popoverPresentationController.

En un entorno horizontalmente compacto, esta opción se comporta igual que UIModalPresentationFullScreen.

Disponible en iOS 8.0 y versiones posteriores.

Referencia UIModalPresentationStyle Reference

sourceView barButtonItem propiedad sourceView o barButtonItem , de lo contrario se bloqueará con el siguiente mensaje:

*** La aplicación de terminación se debe a la excepción no detectada ''NSGenericException'', motivo: ''UIPopoverPresentationController (***) debe tener un valor sourceView o barButtonItem no nulo establecido antes de que se produzca la presentación.''

Para anclar la flecha emergente correctamente, también debe especificar la propiedad sourceRect .

avc.modalPresentationStyle = UIModalPresentationPopover; avc.popoverPresentationController.sourceView = self.view; avc.popoverPresentationController.sourceRect = theButton.frame; [self presentViewController:avc animated:YES completion:nil];

Consulte sourceView y sourceRect para más detalles.