在7.3 / 9/2 + Swift中如何禁用旋转animation,设备何时旋转?

这个问题严格的关于iOS9 +

假设你有一个普通的现代应用程序(自动布局,故事板,通用),它允许所有四个旋转位置

在这里输入图像说明

你希望它以正常的方式自动旋转,所以当用户从横向到纵向旋转设备时,它会改变为新的基于约束的布局

但是在用户旋转设备的时候,你只需要没有animation。 你想要它只是“点击”新的横向或直立的布局。

我能做到这一点的唯一方法是增加:

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

一个视图控制器,一个最高或接近最高的VC,用于保存容器视图的其余部分或场景中的任何内容。

这与使用willRotateToInterfaceOrientation / didRotateFromInterfaceOrientation(现在在现代iOS中不能使用)的古老想法基本相同,可以将animation开关。

但是有很多问题

  • 这不适用于AppWide,它是一团糟,它是基于场景的

  • 关掉所有的animation似乎很不好

  • 你可以看到各种赛道

这个问题严格的关于iOS9 +

这些天,有没有更好的方法来closures支持风景/肖像的应用程序中的旋转animation?

这个问题严格的关于iOS9 +

你可以使用Method swizzling

这意味着要在应用程序中的任何视图控制器上更改对“viewWillTransitionToSize”的调用,而不是调用“genericViewWillTransitionToSize”。
这样你就不必使用子类,或者在应用程序中重复使用代码。

有了这样的伤心,你应该非常热衷于争吵,大国有很大的责任。 把这个类放在一个你或者你之后的程序员知道如何find它的地方,当他想要把旋转animation返回到视图控制器的时候。

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

据我所知,没有更好的办法。

虽然你可以用这个方法声明一个单独的类,并使你的应用程序中的所有视图控制器成为它的子类。

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

在旋转设备时,视图需要更改其大小的所有视图控制器都会接收viewWillTransitionToSize方法调用。

您需要在您的应用程序中声明一次这个新类,然后将所有视图控制器声明从类MyViewController: UIViewController更改为MyViewController: NoRotateAnimationVC

提供的实现将禁用所有animation,并在转换后重新启用它们。 所以如果你只在一个视图控制器中覆盖这个方法,只要它的视图会因为一个旋转而改变大小,它将在任何地方禁用旋转animation。 但是,如果该视图控制器不活动,animation将不会被禁用。