1

I'm trying to animate 2 constraints(which determine position on y axis and height) of the same view at same time. The problem is, that they are dependent, by which I mean, they work together to determine the same property. The picture shows what I mean.

enter image description here

2 arrows depict constraints. The upper one sets the distance between upper view and bottom view, the bottom constrains sets the distance between bottom layout guide and bottom view. The bottom view slides from below the view and stops at the position you are currently seeing. The height is set with animating constraints. This is the code I'm using to make animation:

        self.toBottomConstraint.constant = 53
        self.toUpperConstraint.constant = 15

        UIView.animateWithDuration(0.2, delay: 0, usingSpringWithDamping: 20, initialSpringVelocity: 20, options: UIViewAnimationOptions.CurveLinear, animations: {
            self.view.layoutIfNeeded()
            }, completion: {_ in})

The code actually works but I'm getting this error.

Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) ... .... .... ....

So how should I animate 2 dependent constraints?

EDIT: //upper view constraints.

enter image description here

// bottom view constraints. BuyButton and collection view are nested inside bottom view

enter image description here

Rishil Patel
  • 1,977
  • 3
  • 14
  • 30
potato
  • 4,479
  • 7
  • 42
  • 99

2 Answers2

4

Depending on how you compose your animation, there're literally infinite ways to set the constraints before and after the animation. Most importantly, you need to decide what the constraints were, before the animation, and what they will be after the animation. For example:

self.toBottomConstraint.constant = 153
self.toUpperConstraint.constant = 0

UIView.animateWithDuration(0.2, delay: 0.0, options: UIViewAnimationOptions.CurveEaseInOut, animations: { () -> Void in
    self.toBottomConstraint.constant = 53
    self.toUpperConstraint.constant = 15
    self.view.layoutIfNeeded()
}, completion: nil)

The code above will animate the bottom view bottom up.

By the way, the console warning message for conflict constraints might be caused by other constraint you set on the bottom view apart from its top and bottom constraints, for example, you might have configured a height constraint for the bottom view, in which case, you need to update the height constraint after the animation.

utogaria
  • 3,662
  • 2
  • 14
  • 12
  • I went and double checked the constraints. These two constraints were the only one setting the height of bottom view. I ended up lowering the priority of one constraint. Now it doesn't throw an error but I'm not sure what this will look like on different screens. – potato Aug 04 '15 at 07:25
  • If you're sure there's no height constraint on the bottom view, then, you can try to disable NSAutoresizingMaskLayoutConstraints by calling: `self.view.translatesAutoresizingMaskIntoConstraints = false`, and see if it make any difference. If it still doesn't help, you can use "[view debugging](https://developer.apple.com/library/ios/recipes/xcode_help-debugger/using_view_debugger/using_view_debugger.html)" in Xcode to check call constraints while the app is running, this should be the best way to find out the unexpected conflicting constraints. – utogaria Aug 04 '15 at 07:47
  • since upper view has a height constraint, perhaps you mean self.bottomView.translatesAutoresizingMaskIntoConstraints = false.(how did you highlight text in coment?) I tried both ways. When self.bottomView... was used, the error is still here. When self.view..... was used the whole view hierarchy is distorted and definitely not what I want. – potato Aug 04 '15 at 09:13
  • I added a screen shot of upper and bottom view constraints. – potato Aug 04 '15 at 09:52
  • yeah it works. But I wanted this to be functional on different displays. If I set a constant height for bottom view, it may look to small on iPad or too big on iPhone4 for example – potato Aug 04 '15 at 11:04
  • I've create a small demo for you, you can check it out if you like: https://s3.amazonaws.com/utogaria/views.zip – utogaria Aug 04 '15 at 11:31
  • FYI, **"how did you highlight text in coment?"**, when you type in something in a comment, you'll see xxx characters left, below that label, there's a text box with yellow background telling you how to format your comment using mini-Markdown formatting. – utogaria Aug 04 '15 at 11:33
  • you sir deserve an upvoat :D – potato Aug 04 '15 at 12:17
2

You're almost there, just move the changing of the constants into the closure and call layoutIfNeeded() earlier too:

self.layoutIfNeeded()

UIView.animateWithDuration(0.2, delay: 0, usingSpringWithDamping: 20, initialSpringVelocity: 20, options: UIViewAnimationOptions.CurveLinear, animations: {
    self.toBottomConstraint.constant = 53
    self.toUpperConstraint.constant = 15

    self.view.layoutIfNeeded()
}, completion: {_ in})

You can read more about animating constraints in another answer about constraint changes.

Community
  • 1
  • 1
ezcoding
  • 2,974
  • 3
  • 23
  • 32
  • Does the toUpperConstraint specify the vertical distance between upper view and bottom view? – ezcoding Aug 04 '15 at 08:09
  • what other constraints does the upper view have? – ezcoding Aug 04 '15 at 09:08
  • I added a screenshot of upper view constraints – potato Aug 04 '15 at 09:18
  • ok. you get the error message, because you'll have to modify the `topSpace` to the `TopLayoutGuide` as well. You are pushing both of your views up, but aren't changing the constraints which define the distance of the upperView to the `TopLayoutGuide`. So if you push your views up, you'll have to subtract from the constant value of the `topSpace` constraint. – ezcoding Aug 04 '15 at 09:27
  • Nono, the only view that is moving is bottom view. The upper view slides from the left, but that does not affect its y position. – potato Aug 04 '15 at 09:35
  • I also added an image of bottom view constraints. – potato Aug 04 '15 at 09:48
  • if you have a constraint between 2 views. changing one constraint affects both of them. that's how constraints are supposed to work. If you say: keep a vertical distance y from bottom view and then you animate your bottom view down or up, it will try to satisfy that constraint. But it can't, because your top view also has a constraint to the top layout guide which says: keep a vertical distance of 20. How can your upper view keep a constraint of 20 to the top and a constraint of 50 to the bottom, if the bottom view changes its constraints? You have to update all constraints involved in this – ezcoding Aug 04 '15 at 10:05
  • I see your point. That's way I am animating 2 constrains, both of them change for the same amount(in my case its 500, this is not evident from the code I gave you because I changed it afterwards). While the constraint (which sets distance) between bottom Layout Guide and bottom view gets bigger, the constraint (which sets distance) between upper view and bottom view gets smaller. I am animating both of the constraints. There should be no conflicting constraints because one is getting smaller and the other one is getting bigger at the same time. Doesn't look iOS sees constraints that way.. – potato Aug 04 '15 at 10:27
  • I see, that you are changing 2 constraints in your code, while 2 others, which are affected by it, are not being changed at all. Change your constraints to the bottom and top Layout Guides as well – ezcoding Aug 04 '15 at 10:30
  • 1
    And if you are changing all of them, make sure, that you corrected the new constants correctly, since the new values aren't equal, the constraints to the top and bottom layout guide will change differently as well – ezcoding Aug 04 '15 at 10:31