禁用屏幕旋转动画

28

我需要禁用屏幕方向改变时的动画效果。这个是否可行?如果不行,是否可以加快动画速度?

需要澄清的是,我不想停止屏幕方向的变化,只是想停止动画效果,希望方向立即改变。


可能是重复的问题:更改或禁用iPhone旋转动画以响应方向变化 - richq
5个回答

50

是的,可以禁用动画,而不会破坏整个界面。以下代码将禁用“黑盒子”旋转动画,而不影响其他动画或方向代码:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
    [UIView setAnimationsEnabled:YES];
}


- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    [UIView setAnimationsEnabled:NO];
  /* Your original orientation booleans*/

    return TRUE;
}

将它放在你的UIViewController中,一切都应该很好。这个方法也可以用于iOS中的任何不需要的动画。

祝你的项目好运。


对于2016年,似乎无法覆盖shouldAutorotateToInterfaceOrientation。以下方法似乎有效,并且不会造成其他问题。

// these DO SEEM TO WORK, 2016
override func willRotateToInterfaceOrientation(
        toInterfaceOrientation:UIInterfaceOrientation, duration:NSTimeInterval)
    {
    UIView.setAnimationsEnabled(false)
    super.willRotateToInterfaceOrientation(toInterfaceOrientation,duration:duration)
    }
override func didRotateFromInterfaceOrientation(
        fromInterfaceOrientation:UIInterfaceOrientation)
    {
    super.didRotateFromInterfaceOrientation(fromInterfaceOrientation)
    UIView.setAnimationsEnabled(true)
    }

但是!! 的确,这两个函数都已经被弃用了。而viewWillTransitionToSize现在将会处理“之前”和“之后”的情况。

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

@teedayf 没问题。在许多需要去除默认动画的地方都很有用。 - Nils Munch
1
我也试过不行...但是加到willRotateToInterfaceOrientation里面就可以了。 - Lawson
2
@Lawson - 顺便说一下,它们现在已经被弃用了。请看编辑! - Fattie
很遗憾,在iOS 8+上已经被弃用了。 - Duck
有没有 SwiftUI 的解决方案? - Andrei Matei

13

在iOS8中,您可以通过在视图控制器的 viewWillTransitionToSize 实现中禁用CALayer动画来禁用旋转动画。

接受答案中提到的反向旋转对于如果您想要自定义过渡(请参阅WWDC 2014“ iOS 8中的视图控制器改进”)非常有用,但如果您只是想防止动画,则不需要使用它。

(注意:实现viewWillTransitionToSize将防止调用在iOS8之前弃用的旋转API。)

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
    [CATransaction begin];
    [CATransaction setDisableActions:YES];
    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
        // You could make a call to update constraints based on the
        // new orientation here.
    } completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
        [CATransaction commit];
    }];
}

1
这个在iPhone上的表现很奇怪,在iPad上屏幕旋转是系统动画 :( - Peter Lapisu
它禁用任何动画,它没有用处。 - Pedro Paulo Amorim

5

根据Nils Munch的回答,这是Swift 3版本:

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    coordinator.animate(alongsideTransition: nil) { (_) in
        UIView.setAnimationsEnabled(true)
    }
    UIView.setAnimationsEnabled(false)
    super.viewWillTransition(to: size, with: coordinator)
}

2
如果我没有记错的话(这种事情我总是需要花一点时间来做正确),willRotateToInterfaceOrientation:duration:willAnimateRotationToInterfaceOrientation:duration:都在动画块内,而didRotateFromInterfaceOrientation:则在动画块之后运行。我相信你需要在willRotate中布置你的视图,使它们出现在旋转后它们不旋转时出现的位置上(如果这样说有意义的话)。这样,动画将从它们原始(正确)的布局到新的(旋转)布局中以与设备旋转相反的方向进行动画,从而创建没有动画的外观。一旦旋转完成,你可以在didRotate中布置你的视图,而不需要动画,给人以它们立即旋转的印象。
清楚明了吗?

很遗憾,在iOS 8+上已经被弃用。 - Duck

0

如果您在视图即将旋转时重新布局视图,我认为当它真正旋转时就不会有动画效果。 我的意思是,编写一个方法,为每个子视图提供新的坐标、框架和位置,并在 willRotateToInterfaceOrientation:duration:willAnimateFirstHalfOfRotationToInterfaceOrientation:duration: 中调用该方法。 (虽然这不是一种聪明的做法。我想知道,为什么您需要无动画效果?)


我正在手动更改模态视图控制器的方向。当我关闭模态视图控制器时,我希望方向已经改变。 - Arlen Anderson
然后,您可以尝试在模态视图控制器出现之前设置父控制器不旋转。然后显示您的模态视图控制器(可能先旋转它),隐藏它,然后父控制器应该与之前一样。我相信。或者也可以尝试玩弄这种组合方式。 - nacho4d
你误解了。父视图只允许一个方向。模态视图有一个切换按钮,可以让你选择方向。例如:父视图在纵向,你打开模态视图并选择横向。模态视图关闭后,父视图变为横向。这都可以工作,但动画效果不太好,我想去掉它。我希望在模态视图关闭时,父视图已经切换了方向。 - Arlen Anderson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接