Ios 在7.3/9/2+;当设备旋转时,如何禁用旋转动画?

Ios 在7.3/9/2+;当设备旋转时,如何禁用旋转动画?,ios,swift,ios9,ios-autolayout,autorotate,Ios,Swift,Ios9,Ios Autolayout,Autorotate,这个问题完全是关于iOS9的+ 假设你有一个普通的现代应用程序(自动布局、故事板、通用),它允许所有四个旋转位置 您希望它以正常方式自动旋转,因此当用户将设备从横向旋转到纵向时,它将更改为新的基于约束的布局 但在用户旋转设备期间,您只需要不播放动画。您希望它只是“单击”到新的横向或垂直布局 我实现这一目标的唯一方法是添加: override func viewWillTransitionToSize(size:CGSize, withTransitionCoordinator c

这个问题完全是关于iOS9的+

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

您希望它以正常方式自动旋转,因此当用户将设备从横向旋转到纵向时,它将更改为新的基于约束的布局

但在用户旋转设备期间,您只需要不播放动画。您希望它只是“单击”到新的横向或垂直布局

我实现这一目标的唯一方法是添加:

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中都不可用)来打开/关闭动画

但也有很多问题

  • 这在应用程序范围内不起作用,这是一个混乱,它是基于场景的

  • 关闭所有动画似乎很糟糕

  • 你可以看到各种各样的赛马场

这个问题完全是关于iOS9的+

现在,在一个支持横向/纵向的应用程序中,有没有更好的方法来关闭旋转动画


这个问题完全是关于iOS9+

据我所知,没有更好的方法来解决这个问题

尽管您可以使用此方法声明一个单独的类,并使应用程序中的所有视图控制器成为其子类

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)}
    }
}
旋转设备时,其视图需要更改其大小的所有视图控制器都将收到
viewwillTransitionOnSize
方法调用


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


提供的实现禁用所有动画,并在转换后重新启用它们。因此,如果仅在一个视图控制器中重写此方法,只要其视图因旋转而改变大小,它将禁用所有位置的旋转动画。但如果视图控制器未激活,动画将不会被禁用。

您可以使用方法滑动

这意味着要将应用程序中任何视图控制器上的调用更改为“ViewWillTransitionOnSize”,改为调用“GenericViewWillTransitionOnSize”。
这样,您就不必在应用程序上使用子类或重复代码

带着这种悲伤,你应该非常小心地大口大口大口地喝,强大的力量带来巨大的责任。将类放在一个您或您之后的下一个程序员知道如何找到它的位置,此时他将希望将旋转动画返回给视图控制器

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

这是哪个版本的iOS?你好,谢谢,当然是iOS9。注意第一句话!可以在模拟器上工作,但不能在真实设备(ipad)上工作
UIView.AreanimationEnabled()
在动画块内返回
true
,这让我感到困惑(因为它以前确实被禁用)。旋转动画块一定有计时问题。。。(
setAnimationEnabled
doc声明:“此方法仅影响调用后提交的动画。如果在现有动画运行时调用此方法,则这些动画将继续运行,直到达到其自然终点。”)您需要在应用程序中声明一次这个新类,然后将所有视图控制器声明从
classmyviewcontroller:UIViewController{…}
更改为
MyViewController:NoRotateAnimationVC{…}
啊,您是说每个视图控制器都必须这样做。很公平。有趣的是,我发现如果你只是随便挑一个——我想甚至是随机的——它确实有效。(我不知道这是否会带来更多的问题。)谢谢again@JoeBlow旋转设备时,其视图需要更改其大小的所有视图控制器都将收到
viewwillTransitionOnSize
方法调用。提供的实现禁用所有动画,并在转换后重新启用它们。因此,如果仅在一个视图控制器中重写此方法,只要其视图因旋转而改变大小,它将禁用所有位置的旋转动画。但如果视图控制器未处于活动状态,动画将不会被禁用。感谢您的精彩解释,bzz。有道理!我想如果它是“顶级”的,并且你知道它将一直出现在应用程序中,那么你可以这样做。再次感谢。我可以在控制器之间转换时禁用旋转动画吗(而不是在控制器内)?