www descargar apple ios8 uipopovercontroller adaptive-layout

ios8 - descargar - Controlador de presentación de iOS 8 determina si realmente es popover



ios iso (8)

El UIPresentationController que administra su controlador de vista lo presenta configurando el modalPresentationStyle en UIModalPresentationPopover .

Según la reference UIViewController :

presentandoViewController

  • El controlador de vista que presentó este controlador de vista. (solo lectura)

modalPresentationStyle

  • 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.

Por lo tanto, podemos determinar si su controlador de vista se encuentra dentro de una ventana emergente o se presenta modalmente al verificar la UIBarButtonItem horizontalSizeClass siguiente manera (asumí que su botón es un UIBarButtonItem )

- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; if (self.presentingViewController.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassRegular) self.navigationItem.leftBarButtonItem = nil; // remove the button }

El lugar más seguro para verificar esto es en viewWillAppear: lo contrario, el presentingViewController puede ser nil .

Estoy usando la nueva capacidad adaptativa "Present As Popover" de iOS 8. He conectado un segmento simple en el StoryBoard para hacer la presentación. Funciona muy bien en un iPhone 6 Plus, ya que presenta la vista como una ventana emergente y en un iPhone 4s se muestra como una vista de pantalla completa (estilo de hoja).

El problema es que cuando se muestra como una vista de pantalla completa, necesito agregar un botón "Listo" a la vista para que se pueda invitar a descontar a controlador. Y no quiero mostrar el botón "hecho" cuando se muestra como una ventana emergente.

Intenté ver las propiedades de presentationController y popoverPresentationController, y no puedo encontrar nada que me diga si realmente se muestra como una ventana emergente.

NSLog( @"View loaded %lx", (long)self.presentationController.adaptivePresentationStyle ); // UIModalPresentationFullScreen NSLog( @"View loaded %lx", (long)self.presentationController.presentationStyle ); // UIModalPresentationPopover NSLog( @"View loaded %lx", (long)self.popoverPresentationController.adaptivePresentationStyle ); // UIModalPresentationFullScreen NSLog( @"View loaded %lx", (long)self.popoverPresentationController.presentationStyle ); // UIModalPresentationPopover

adaptivePresentationStyle siempre devuelve UIModalPresentationFullScreen y presentationStyle siempre devuelve UIModalPresentationPopover

Al mirar el UITraitCollection encontré un rasgo llamado "_UITraitNameInteractionModel" que solo estaba establecido en 1 cuando en realidad se mostraba como un Popover. Sin embargo, Apple no proporciona acceso directo a ese rasgo a través de traitCollection de popoverPresentationController.


He probado todas las soluciones presentadas en este post. Lo sentimos, ninguno funciona correctamente en todos los casos. Por ejemplo, en el iPad, el estilo de presentación de vista dividida puede cambiar al arrastrar la línea de vista dividida, por lo que necesitamos una notificación específica para eso. Después de algunas horas de investigaciones encontré una solución en una muestra de manzana (swift): https://developer.apple.com/library/ios/samplecode/AdaptivePhotos/Introduction/Intro.html#//apple_ref/doc/uid/TP40014636

Aquí está la misma solución en obj-c.

Primero en la función prepareForSegue establecer el delegado popoverPresentationController. También se puede configurar en MyViewController "init", pero no en "viewDidLoad" (porque primero se llama a willPresentWithAdaptiveStyle antes de viewDidLoad).

MyViewController *controller = [segue destinationViewController]; controller.popoverPresentationController.delegate = (MyViewController *)controller;

Ahora el objeto MyViewController recibirá esta notificación cada vez que iOS cambie el estilo de presentación, incluida la primera presentación. Aquí hay una implementación de ejemplo que muestra / oculta el botón "Cerrar" en navigationController:

- (void)presentationController:(UIPresentationController *)presentationController willPresentWithAdaptiveStyle:(UIModalPresentationStyle)style transitionCoordinator:(nullable id<UIViewControllerTransitionCoordinator>)transitionCoordinator { if (style == UIModalPresentationNone) { // style set in storyboard not changed (popover), hide close button self.topViewController.navigationItem.leftBarButtonItem = nil; } else { // style changed by iOS (to fullscreen or page sheet), show close button UIBarButtonItem *closeButton = [[UIBarButtonItem alloc] initWithTitle:@"Close" style:UIBarButtonItemStylePlain target:self action:@selector(closeAction)]; self.topViewController.navigationItem.leftBarButtonItem = closeButton; } } - (void)closeAction { [self.presentingViewController dismissViewControllerAnimated:YES completion:nil]; }


La forma oficial de implementar esto es primero quitar el botón Hecho de su controlador de vista y segundo, cuando se adapte para compactar incrustar su controlador de vista en un controlador de navegación, agregando el botón hecho como un elemento de navegación:

func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle { return UIModalPresentationStyle.FullScreen } func presentationController(controller: UIPresentationController, viewControllerForAdaptivePresentationStyle style: UIModalPresentationStyle) -> UIViewController? { let navigationController = UINavigationController(rootViewController: controller.presentedViewController) let btnDone = UIBarButtonItem(title: "Done", style: .Done, target: self, action: "dismiss") navigationController.topViewController.navigationItem.rightBarButtonItem = btnDone return navigationController } func dismiss() { self.dismissViewControllerAnimated(true, completion: nil) }

Tutorial completo


La mejor manera (menos maloliente) que he encontrado para hacer esto es usar UIPopoverPresentationControllerDelegate .

• Asegúrese de que el controlador de vista presentado esté configurado como UIPopoverPresentationControllerDelegate en el UIPopoverPresentationController se usa para administrar la presentación. Estoy usando un Storyboard así que prepareForSegue: en prepareForSegue:

segue.destinationViewController.popoverPresentationController.delegate = presentedVC;

• Cree una propiedad en el controlador de vista presentada para realizar un seguimiento de este estado:

@property (nonatomic, assign) BOOL amDisplayedInAPopover;

• Y agregue el siguiente método de delegado (o agregue a su método de delegado existente):

- (void)prepareForPopoverPresentation:(UIPopoverPresentationController *)popoverPresentationController { // This method is only called if we are presented in a popover self.amDisplayedInAPopover = YES; }

• Y finalmente, en viewWillAppear: - viewDidLoad: es demasiado temprano, se llama al método de preparación de delegado entre viewDidLoad: y viewWillAppear:

if (self.amDisplayedInAPopover) { // Hide the offending buttons in whatever manner you do so self.navigationItem.leftBarButtonItem = nil; }

Edición: método más sencillo!

Simplemente configure el delegado (asegurándose de que su UIPopoverPresentationControllerDelegate presentado adopte el UIPopoverPresentationControllerDelegate ):

segue.destinationViewController.popoverPresentationController.delegate = presentedVC;

Y suministrar el método:

- (void)prepareForPopoverPresentation:(UIPopoverPresentationController *)popoverPresentationController { // This method is only called if we are presented in a popover // Hide the offending buttons in whatever manner you do so self.navigationItem.leftBarButtonItem = nil; }


Mi solución complicada, funciona perfectamente.

En el PopoverViewController de viewDidLoad .

if (self.view.superview!.bounds != UIScreen.main.bounds) { print("This is a popover!") }

La idea es simple, el tamaño de la vista de un Popover nunca es igual al tamaño de la pantalla del dispositivo a menos que no sea un Popover.


Qué tal si

if (self.modalPresentationStyle == UIModalPresentationPopover)

Esta trabajando para mi


Verifico para ver si la dirección de flecha popPortPresentationController se establece después de que se haya diseñado la vista. Para mis propósitos, esto funciona bastante bien y cubre el caso de ventanas emergentes en dispositivos de pantalla más pequeños.

override func viewWillAppear(animated: Bool) { super.viewWillAppear(animated) if (popoverPresentationController?.arrowDirection != UIPopoverArrowDirection.Unknown) { // This view controller is running in a popover NSLog("I''m running in a Popover") } }


Solución que funciona con multitarea.

Asignar el controlador de presentación como delegado del popover

... controller.popoverPresentationController.delegate = controller; [self presentViewController:controller animated:YES completion:nil];

Luego, en el controlador, implementa los métodos de delegado:

- (void)presentationController:(UIPresentationController *)presentationController willPresentWithAdaptiveStyle:(UIModalPresentationStyle)style transitionCoordinator:(id<UIViewControllerTransitionCoordinator>)transitionCoordinator { if (style != UIModalPresentationNone) { // Exited popover mode self.navigationItem.leftBarButtonItem = button; } } - (void)prepareForPopoverPresentation:(UIPopoverPresentationController *)popoverPresentationController { // Entered popover mode self.navigationItem.leftBarButtonItem = nil; }