ios ios8 orientation uiinterfaceorientation landscape-portrait

¿Cuál es la forma "correcta" de manejar los cambios de orientación en iOS 8?



ios8 orientation (4)

Apple recomienda usar clases de tamaño como una medida aproximada de cuánto espacio de pantalla está disponible, para que su interfaz de usuario pueda cambiar significativamente su diseño y apariencia. Tenga en cuenta que un iPad en vertical tiene las mismas clases de tamaño que en horizontal (ancho normal, altura normal). Esto significa que su IU debe ser más o menos similar entre las dos orientaciones.

Sin embargo, el cambio de vertical a horizontal en un iPad es lo suficientemente significativo como para que necesite hacer algunos ajustes más pequeños en la interfaz de usuario, aunque las clases de tamaño no hayan cambiado. Dado que los métodos relacionados con la orientación de la interfaz en UIViewController han quedado en desuso, Apple ahora recomienda implementar el siguiente método nuevo en UIViewController como reemplazo:

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinator { [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; // Code here will execute before the rotation begins. // Equivalent to placing it in the deprecated method -[willRotateToInterfaceOrientation:duration:] [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) { // Place code here to perform animations during the rotation. // You can pass nil or leave this block empty if not necessary. } completion:^(id<UIViewControllerTransitionCoordinatorContext> context) { // Code here will execute after the rotation has finished. // Equivalent to placing it in the deprecated method -[didRotateFromInterfaceOrientation:] }]; }

¡Excelente! Ahora está recibiendo devoluciones de llamada justo antes de que comience la rotación, y después de que finalice. Pero, ¿qué hay de saber realmente si la rotación es vertical o horizontal?

Apple recomienda pensar en la rotación como simplemente un cambio en el tamaño de la vista principal. En otras palabras, durante una rotación de iPad de vertical a horizontal, puede pensar en ella como la vista de nivel raíz simplemente cambiando sus bounds.size de {768, 1024} a {1024, 768} . Entonces, sabiendo esto, debe usar el size pasado a viewWillTransitionToSize:withTransitionCoordinator: método anterior para determinar si está rotando a vertical u horizontal.

Si desea una forma aún más fluida de migrar el código heredado a la nueva forma de hacer las cosas de iOS 8, considere usar esta categoría simple en UIView, que puede usarse para determinar si una vista es "vertical" u "horizontal" en función de su Talla.

Recordar:

  1. Debe usar clases de tamaño para determinar cuándo mostrar IU fundamentalmente diferentes (por ejemplo, una IU "similar a iPhone" frente a una IU "similar a iPad")
  2. Si necesita hacer ajustes más pequeños en su IU cuando las clases de tamaño no cambian pero el tamaño de su contenedor (vista principal) sí lo hace, como cuando un iPad gira, use viewWillTransitionToSize:withTransitionCoordinator: callback en UIViewController.
  3. Cada vista en su aplicación solo debe tomar decisiones de diseño basadas en el espacio que se le ha dado para el diseño. Deje que la jerarquía natural de vistas caiga en cascada esta información.
  4. Del mismo modo, no use el statusBarOrientation , que es básicamente una propiedad de nivel de dispositivo, para determinar si desea diseñar una vista para "retrato" frente a "paisaje". La orientación de la barra de estado solo debe ser utilizada por el código que se ocupa de cosas como UIWindow que realmente viven en el nivel raíz de la aplicación.

¿Puede alguien decirme el enfoque "correcto" o "mejor" para trabajar con orientaciones de interfaz vertical y horizontal en iOS 8? Parece que todas las funciones que quiero usar para ese propósito están en desuso en iOS 8, y mi investigación no ha encontrado una alternativa clara y elegante. ¿De verdad se supone que debo mirar el ancho y la altura para determinar por mí mismo si estamos en modo vertical u horizontal?

Por ejemplo, en mi controlador de vista, ¿cómo debo implementar el siguiente pseudocódigo?

if we are rotating from portrait to landscape then do portrait things else if we are rotating from landscape to portrait then do landscape things


Basado en la respuesta muy bien detallada (y aceptada) de smileyborg, aquí hay una adaptación usando swift 3:

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { super.viewWillTransition(to: size, with: coordinator) coordinator.animate(alongsideTransition: nil, completion: { _ in self.collectionView.collectionViewLayout.invalidateLayout() }) }

Y en la implementación UICollectionViewDelegateFlowLayout ,

public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { // retrieve the updated bounds let itemWidth = collectionView.bounds.width let itemHeight = collectionView.bounds.height // do whatever you need to do to adapt to the new size }


Desde la perspectiva de la interfaz de usuario, creo que el uso de Clases de tamaño es el enfoque recomendado por Apple para manejar interfaces en diferentes orientaciones, tamaños y escalas.

Consulte la sección: Rasgos Describa la clase de tamaño y la escala de una interfaz aquí: https://developer.apple.com/library/ios/releasenotes/General/WhatsNewIniOS/Articles/iOS8.html

"iOS 8 agrega nuevas características que hacen que lidiar con el tamaño y la orientación de la pantalla sea mucho más versátil".

Este también es un buen artículo: https://carpeaqua.com/thinking-in-terms-of-ios-8-size-classes/

EDITAR Enlace actualizado: https://carpeaqua.com/2014/06/14/thinking-in-terms-of-ios-8-size-classes/ (Crédito: Koen)


Simplemente uso el Centro de notificaciones:

Agregue una variable de orientación (se explicará al final)

//Above viewdidload var orientations:UIInterfaceOrientation = UIApplication.sharedApplication().statusBarOrientation

Agregar notificación cuando aparece la vista

override func viewDidAppear(animated: Bool) { NSNotificationCenter.defaultCenter().addObserver(self, selector: "orientationChanged:", name: UIDeviceOrientationDidChangeNotification, object: nil) }

Eliminar notificación cuando la vista desaparece

override func viewWillDisappear(animated: Bool) { NSNotificationCenter.defaultCenter().removeObserver(self, name: UIDeviceOrientationDidChangeNotification, object: nil) }

Obtiene orientación actual cuando se activa la notificación

func orientationChanged (notification: NSNotification) { adjustViewsForOrientation(UIApplication.sharedApplication().statusBarOrientation) }

Verifica la orientación (vertical / horizontal) y maneja eventos

func adjustViewsForOrientation(orientation: UIInterfaceOrientation) { if (orientation == UIInterfaceOrientation.Portrait || orientation == UIInterfaceOrientation.PortraitUpsideDown) { if(orientation != orientations) { println("Portrait") //Do Rotation stuff here orientations = orientation } } else if (orientation == UIInterfaceOrientation.LandscapeLeft || orientation == UIInterfaceOrientation.LandscapeRight) { if(orientation != orientations) { println("Landscape") //Do Rotation stuff here orientations = orientation } } }

La razón por la que agrego una variable de orientación es porque cuando se realiza la prueba en un dispositivo físico, se recibe una notificación de orientación en cada movimiento menor en el dispositivo, y no solo cuando gira. Agregar las declaraciones var y if solo llama al código si cambia a la orientación opuesta.