ios swift ios9 ios-autolayout auto-rotation

ios - En 7.3/9/2+Swift, ¿cómo deshabilitar la animación de rotación, cuando el dispositivo gira?



ios9 ios-autolayout (2)

Esta pregunta es estrictamente sobre iOS9 +

Digamos que tienes una aplicación moderna ordinaria (autolayout, storyboard, universal) que permite las cuatro posiciones de rotación

desea que se gire automáticamente de la forma normal, por lo que cambiará a sus nuevos diseños basados ​​en restricciones cuando el usuario gire el dispositivo de horizontal a vertical

Pero simplemente no desea ninguna animación durante la rotación del dispositivo por parte del usuario. Desea que simplemente "haga clic" en el nuevo diseño lateral o vertical.

La única forma en que he podido lograr esto es agregando:

override func viewWillTransitionToSize(size:CGSize, withTransitionCoordinator coordinator:UIViewControllerTransitionCoordinator) { coordinator.animateAlongsideTransition(nil, completion: {_ in UIView.setAnimationsEnabled(true) }) UIView.setAnimationsEnabled(false) super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator); }

a un controlador de vista, un VC más alto o más alto que contiene el resto de las vistas del contenedor o lo que sea en la escena.

Esta es básicamente la misma idea antigua de usar willRotateToInterfaceOrientation / didRotateFromInterfaceOrientation (ambos ahora inutilizables en el iOS moderno) para activar y desactivar las animaciones.

Sin embargo hay muchos problemas.

  • Esto no funciona con AppWide, es un desastre, está basado en la escena.

  • Parece muy malo apagar todas las animaciones

  • Puedes ver todo tipo de hipódromo.

Esta pregunta es estrictamente sobre iOS9 +

En estos días, ¿hay alguna forma mejor de desactivar las animaciones de rotación en una aplicación que admita paisaje / retrato?

Esta pregunta es estrictamente sobre iOS9 +


Puedes usar el método swizzling .

Esto significa que vamos a cambiar las llamadas a "viewWillTransitionToSize" en cualquier controlador de vista en su aplicación para llamar a "genericViewWillTransitionToSize" en su lugar.
De esta manera, no tiene que usar subclases o códigos repetidos sobre su aplicación.

Con eso triste, deberías tener mucho cuidado con los swizzling, con gran poder conlleva una gran responsabilidad. Coloque la clase en un lugar en el que usted, o el siguiente programador después de usted, sabrá cómo encontrarla, cuando querrá devolver las animaciones de rotación para ver los controladores.

extension UIViewController { public override static func initialize() { struct Static { static var token: dispatch_once_t = 0 } dispatch_once(&Static.token) { let originalSelector = #selector(UIViewController.viewWillTransitionToSize(_:withTransitionCoordinator:)) let swizzledSelector = #selector(UIViewController.genericViewWillTransitionToSize(_:withTransitionCoordinator:)) let originalMethod = class_getInstanceMethod(self, originalSelector) let swizzledMethod = class_getInstanceMethod(self, swizzledSelector) let didAddMethod = class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod)) if didAddMethod { class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)) } else { method_exchangeImplementations(originalMethod, swizzledMethod); } } } // MARK: - Method Swizzling func genericViewWillTransitionToSize(size:CGSize, withTransitionCoordinator coordinator:UIViewControllerTransitionCoordinator) { self.genericViewWillTransitionToSize(size, withTransitionCoordinator: coordinator) coordinator.animateAlongsideTransition(nil, completion: {_ in UIView.setAnimationsEnabled(true) }) UIView.setAnimationsEnabled(false) } }


Que yo sepa, no hay mejor manera de hacerlo.

Aunque puede declarar una clase separada con este método y hacer que todos los controladores de vista en su aplicación sean sus subclases.

class NoRotateAnimationVC: UIViewController { override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) { super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator) UIView.setAnimationsEnabled(false) coordinator.notifyWhenInteractionEndsUsingBlock {_ in UIView.setAnimationsEnabled(true)} } }

Cuando gira el dispositivo, todos los controladores de vista cuyas vistas necesitan cambiar sus tamaños reciben la viewWillTransitionToSize método viewWillTransitionToSize .

MyViewController: UIViewController declarar esta nueva clase una vez en su aplicación y luego cambiar todas las declaraciones de su controlador de vista de la clase MyViewController: UIViewController a MyViewController: NoRotateAnimationVC .

La implementación provista desactiva todas las animaciones y las vuelve a habilitar después de la transición. Por lo tanto, si reemplaza este método en un solo Controlador de vista, siempre que su vista cambie de tamaño como resultado de una rotación, deshabilitará las animaciones de rotación en todas partes. Pero si ese controlador de vista no está activo, las animaciones no se desactivarán.