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 { }
}
当 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 { }
}