Disable orientation change rotation animation
Asked Answered
C

5

28

I need to disable the animation that plays when the orientation changes. Is this possible? If not, is it possible to speed it up?

Just to clarify, i don't want to stop the orientation change, just the animation. I want an instant orientation change.

Chlores answered 27/11, 2010 at 3:57 Comment(1)
possible duplicate of Change or disable the iPhone rotating animation when orientation changesParasympathetic
G
2

If I remember correctly (this is always the sort of thing I have to play around with for a moment to get right) willRotateToInterfaceOrientation:duration: and willAnimateRotationToInterfaceOrientation:duration: are both inside the animation block, while didRotateFromInterfaceOrientation: runs after the animation block. I believe you would need to lay out your views in willRotate so they appear in the position in which they would appear after the rotation had they not rotated (if that makes sense). This way the animation will animate them from their original (correct) layout to the new (rotated) layout in the opposite direction that the device rotates, creating the appearance of no animation. Once the rotation is complete, you can lay out your views, without animation, in didRotate, giving the impression that they rotate instantly.

Clear as mud, no?

Griner answered 27/11, 2010 at 5:38 Comment(1)
unfortunately this is deprecated on iOS 8+Dished
B
50

Yes, it is possible to disable the animation, without breaking everything apart.

The following codes will disable the "black box" rotation animation, without messing with other animations or orientation code:

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


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

    return TRUE;
}

Place it in your UIViewController and all should be well. Same method can be applied to any undesired animation in iOS.

Best of luck with your project.


For 2016, it appears shouldAutorotateToInterfaceOrientation is not available to be overridden. The following does seem to work, and cause no other harm.

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

However!! Indeed both these functions are deprecated. viewWillTransitionToSize now takes care of both the "before" and "after".

override func viewWillTransitionToSize(size:CGSize,
       withTransitionCoordinator coordinator:UIViewControllerTransitionCoordinator)
    {
    coordinator.animateAlongsideTransition(nil, completion:
        {_ in
        UIView.setAnimationsEnabled(true)
        })
    UIView.setAnimationsEnabled(false)
    super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator);
    }
Balbur answered 9/6, 2011 at 12:6 Comment(5)
@teedayf No problem. Its useful in many places where you want the default animations gone.Balbur
Didn't work for me either... but adding it to willRotateToInterfaceOrientation did work.Misbeliever
@Misbeliever - FWIW, those are now deprecated. See edit!Halutz
unfortunately this is deprecated on iOS 8+Dished
any solution for swiftui ?Beattie
R
13

In iOS8 you can disable rotation animations by disabling CALayer animations in your view controller's implementation of viewWillTransitionToSize.

The inverse rotation mentioned in the accepted answer is useful if you want to customize the transition (see WWDC 2014 'View Controller Advancements in iOS 8') but not if you just want to prevent animation.

(N.B. Implementing viewWillTransitionToSize will prevent the deprecated pre-iOS8 rotation APIs from being called.)

- (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];
    }];
}
Restaurateur answered 2/4, 2015 at 0:32 Comment(2)
this works strangely only for iPhone, on iPad the screen rotation is system animated :(Worm
It disable any animation, It isn't useful.Transatlantic
I
5

Based on Nils Munch's Answer, this is the Swift 3 version:

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)
}
Individualist answered 23/1, 2017 at 15:3 Comment(0)
G
2

If I remember correctly (this is always the sort of thing I have to play around with for a moment to get right) willRotateToInterfaceOrientation:duration: and willAnimateRotationToInterfaceOrientation:duration: are both inside the animation block, while didRotateFromInterfaceOrientation: runs after the animation block. I believe you would need to lay out your views in willRotate so they appear in the position in which they would appear after the rotation had they not rotated (if that makes sense). This way the animation will animate them from their original (correct) layout to the new (rotated) layout in the opposite direction that the device rotates, creating the appearance of no animation. Once the rotation is complete, you can lay out your views, without animation, in didRotate, giving the impression that they rotate instantly.

Clear as mud, no?

Griner answered 27/11, 2010 at 5:38 Comment(1)
unfortunately this is deprecated on iOS 8+Dished
M
0

if you re-layout your views when the view is about to be rotated I think when it really rotates it won't have animations. I mean, write a method with the new coordinates, frames, positions for each subview and call that method in willRotateToInterfaceOrientation:duration: or willAnimateFirstHalfOfRotationToInterfaceOrientation:duration: (This is not a smart way of doing things though. I wonder, why do you need no-animation?)

Mend answered 27/11, 2010 at 4:19 Comment(3)
I'm manually changing orientation in a modal view controller. When i dismiss the modal view controller i want the orientation to have already changed.Chlores
Then you can try to set your parent controller not to rotate just before the modal view controller appears. Then show your modal view controller(maybe rotate it first), hide it, and the parent controller should be just as before. I believe. Or maybe try playing with this kind of conbinationsMend
You misunderstand. The parent view only allows one orientation. The modal view has a toggle button which allows you to choose which orientation. For example: the parent view is in portrait, you open the modal view and select landscape. The modal dismisses and the parent view goes to landscape orientation. This all works, but the animation is clunky and i'd like to get rid of it. I'd like the parent view to have already switched orientation when the modal view dismisses.Chlores

© 2022 - 2024 — McMap. All rights reserved.