ViewController 方向变化不是动画的

ViewController orientation change isn't animated

当 iPhone 将其方向从纵向更改为横向时,我正在尝试调整一些视图,反之亦然。在 iOS8 上一切正常,但不幸的是,更改不是动态的,而是在 iOS9 上立即发生。这是我在模态 UIViewController 中通过自定义转换呈现的代码:

override func shouldAutorotate() -> Bool {
    return true
}

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.AllButUpsideDown
}

override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
    return .Portrait
}

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)

    let changeToPortrait = size.width < size.height
    coordinator.animateAlongsideTransition({ (context) -> Void in
        //show portrait
        if changeToPortrait {
            //do view changes...
        }

        //show landscape
        else {
            //undo view changes...
        }
    }) { (context) -> Void in
        print("done")
    }
}

如果我打印 coordinator.isAnimated() 它说 false 因此 coordinator.transitionDuration() 也是 0.0.

我需要做什么才能使过渡变化动画化?

感谢您的帮助!

看看你的 application:didFinishLaunchingWithOptions: 处理程序。似乎如果您手动创建应用程序的 UIWindow 对象,则会触发 iOS9 旋转问题。

我不确定确切的原因,但在我们的应用程序中,我们能够通过删除操作 UIWindow 的代码并让情节提要系统对其进行初始化来解决问题。

这种行为可能是因为您在 application:didFinishLaunchingWithOptions: 方法中将自定义 UIWindow 子类设置为 AppDelegate 的 window 属性,如另一个答案中提到的端粒.

如果需要在iOS9中使用UIWindow子类,为AppDelegate的window属性实现一个自定义getter来维护方向改变动画。

Apple 的 documentation 对于 UIApplicationDelegate 的 window 属性 说:

"...you must implement the getter method of this property and use it to create and return your custom window."

通常的做法是直接在application:didFinishLaunchingWithOptions:中设置window属性。相反,在您的 AppDeleate 中,像这样实现自定义 getter(感谢 Tomas Camin 提供的代码,找到 here):

Objective-C

- (MyCustomWindow *)window
{    
    static MyCustomWindow *customWindow = nil;
    if (!customWindow) customWindow = [[MyCustomWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    return customWindow;
}

Swift

var customWindow: MyCustomWindow?    
var window: UIWindow? {
    get {
        customWindow = customWindow ?? MyCustomWindow(frame: UIScreen.mainScreen().bounds)
        return customWindow
    }
    set { }
}