B.S.
B.S.

Reputation: 21726

UIView stops animation after Device rotation

I have some view and image view.

_contentView = [[UIView alloc] initWithFrame:self.bounds];
_contentView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
....

UIImageView *imageView = [[UIImageView alloc] initWithImage:someImage];
[_contentView addSubview:imageView];

This imageView runs some animation.

[UIView animateWithDuration:1.6f delay:0.0 options:UIViewAnimationOptionAllowUserInteraction |UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat animations:^{
    imageView.center = somePoint;
} completion:^(BOOL finished) {

}];

The problem is that after rotation animation stops. If i change autoresizing mask of the _contentView to flexible bounds animation continues after rotation. But i need it to be with flexible size. Can someone explain why animation stops after rotation?

Upvotes: 3

Views: 969

Answers (3)

Fattie
Fattie

Reputation: 12582

For 2019 ..

The two secrets are this:

1. You MUST reset the value before restarting animation

I actually do not know why - it's completely mysterious - but that's a fact.

2. You MUST restart it in the coordinator completion.

It will NOT work anywhere else, such as in the body of willTransition.

So ...

You have an animating constraint ..

@IBOutlet var slider: NSLayoutConstraint!

(Let's say the initial value is "55")

You continuously animate it to make a wrapping scroll, let's say:

func slide() {
    let w = sliderView.frame.width

    ////////// SECRET TIP ------->
    slider.constant = 55
    ////////// <--------SECRET TIP

    view.layoutIfNeeded()
    UIView.animate(withDuration: 10, delay: 0,
      options: [.repeat, .curveLinear, .beginFromCurrentState],
      animations:{ [weak self] in
        self?.slider.constant = w
        self?.view.layoutIfNeeded()
    })
}

Delete the Secret Tip line and it simply won't work - try it!

You begin when the screen appears ..

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    slide()
}

When the screen is rotated, you continue the animation:

override func willTransition(to newCollection: UITraitCollection,
  with coordinator: UIViewControllerTransitionCoordinator) {
    super.willTransition(to: newCollection, with: coordinator)
    coordinator.animate(alongsideTransition: { _ in
    },completion: { [weak self] _ in
        self?.slide()
    })
}

That's it!

(Note that in fact you actually DON'T need to cancel, pause, or otherwise manipulate your animation: iOS will handle it smoothly with the above.)

Upvotes: 2

Genevios
Genevios

Reputation: 1145

I have the same problem, maybe u use this void? Just set [UIView setAnimationsEnabled:YES] for activate animation again. I hope this solution will be help to you.

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

Upvotes: 0

moray95
moray95

Reputation: 977

Make the device rotation disabled while the animation is playing and after the animation, rotate the screen if the device has been rotated during the animation. This should solve the problem.

Upvotes: -1

Related Questions