-2

I'm trying a simple animation by moving a subclass of UIView when a button is pressed. When the button is pressed the view moves xx units away from the original position, the bug is that it comes back to the original position after going xx units away. I want it to stop at the new position. Whats wrong in my code?

[UIView animateWithDuration:0.5f animations:^{
    self.analogStick.frame = CGRectOffset(self.analogStick.frame, 0, -10);
}];
Rakshith G B
  • 816
  • 2
  • 8
  • 24
  • 1
    The problem is that you're animating a view for which there are auto layout constraints defined. To animate this, you have to add an outlet for the top constraint, change its `constant` property, and then animate the call to `layoutIfNeeded`. See http://stackoverflow.com/a/28329399/1271826. – Rob Jul 10 '16 at 08:44
  • @Rob That explains when you're loading the view for the first time and the animation appears, will it work even after the view is loaded? Dynamically update position everytime the button is pressed? – Rakshith G B Jul 10 '16 at 08:48
  • 1
    Yes, on the tap of the button, adjust the top constraint's `constant`, and then animate the call to `layoutIfNeeded`. – Rob Jul 10 '16 at 08:49
  • It doesn't animate. It just appears to the new position,`self.top.constant = -120; [UIView animateWithDuration:2.0f animations:^{self.analogStick.layoutIfNeeded;}];` – Rakshith G B Jul 10 '16 at 09:57
  • See the discussion under http://stackoverflow.com/a/12926646/1271826 for other thoughts. But this is the way to animate constraints. Make sure you're calling `layoutIfNeeded` on the appropriate superview. – Rob Jul 10 '16 at 10:25
  • @Rob Everyone suggests to use it in ViewDidAppear, but then I'm using it in the button method Ive created. I can't use it in ViewDidAppear. – Rakshith G B Jul 10 '16 at 10:32
  • All of those comments about `viewDidAppear` are just warnings for people who inadvertently try to do it in `viewDidLoad` (which is too early in the view configuration process). But the process of animating a constraint after that point is merely `self.topConstraint.constant = -120; [UIView animateWithDuration:2.0 animations:^{ [self.someView layoutIfNeeded] }];`. If that's not working for you, there's something else going on (e.g. the view for which you called `layoutIfNeeded` is not right; you're not doing it on main thread; etc.). – Rob Jul 10 '16 at 10:36
  • @Rob Yes, thats the exact code I used and it didn't work. How do I run it on the main thread? – Rakshith G B Jul 10 '16 at 11:11
  • Are you running your code from a background thread? If so, make sure to dispatch this animation code back to the main thread with `dispatch_async(dispatch_get_main_queue(), ^{ ... });`. – Rob Jul 10 '16 at 15:56
  • Watch WWDC 2015, there are bunch of auto layout related talks that explain how to animate constraints. – pronebird Jul 10 '16 at 15:58
  • @Rob tried it with dispatch_async, still din't work. – Rakshith G B Jul 10 '16 at 18:41
  • And are you getting an errors/warnings on the console? – Rob Jul 10 '16 at 19:18
  • @Rob Nothing. The console is blank. – Rakshith G B Jul 10 '16 at 19:19
  • Bottom line, you have to provide a [minimal, complete, verifiable example](http://stackoverflow.com/help/mcve) of the problem. Because all of us animate views with constraints all the time without incident and we can't help you if we cannot reproduce your problem. So, create a blank project with a view with a button and a view to be moved with a top constraint, and see if you can reproduce your problem in that simplified environment. Once you identify the elements necessary to reproduce your problem, update your question accordingly. – Rob Jul 10 '16 at 19:19

1 Answers1

1

Connect the layout constraints as IBOutlets from Interface Builder into the code. Then in the beginning of the block, set the constraint's constant to the desired value e.g. setting the left constraint to superview to its constant - 10.

Then, inside the animation block code, just call [self layoutIfNeeded]. Do not set the frame in any way when you are using constraints (you can use 3D transforms though I personally don't recommend it unless you know exactly what you are doing).

Can Poyrazoğlu
  • 33,241
  • 48
  • 191
  • 389