4

I try to create a UIView that is representing a page whose size is the same as the device screen. Since the app supports orientation, I am using AutoLayout to construct it.

It works fine until I try to animate the page to slide in from the right. Here is the best I could come up with after some research:

myView = UIView()
myView.backgroundColor = UIColor.orangeColor()
parentView.addSubview(myView)

myView.translatesAutoresizingMaskIntoConstraints = false
myView.leftAnchor.constraintEqualToAnchor(parentView.rightAnchor).active = true
myView.widthAnchor.constraintEqualToAnchor(parentView.widthAnchor).active = true
myView.heightAnchor.constraintEqualToAnchor(parentView.heightAnchor).active = true

UIView.animateWithDuration(Double(1.0), animations: {
    self.myView.leftAnchor.constraintEqualToAnchor(self.parentView.leftAnchor).active = true
    self.myView.layoutIfNeeded()
})

With the code above, the page myView slides in from the top-left corner, which is not what I am expecting and the log also says Unable to simultaneously satisfy constraints.

Any advise to help me and correct me for better understanding AutoLayout and animation is very much appreciated. Thanks.

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
Joe Huang
  • 6,296
  • 7
  • 48
  • 81
  • You missed the top anchor. – dasdom Dec 21 '15 at 17:14
  • @dasdom even I add the top anchor, it's the same. The problem is that I thought I was overwriting an existing rules but actually I am creating new rules. So the solution is to deactivate some rules first before creating new ones. I think I have found the solution, I will post the answer later. – Joe Huang Dec 21 '15 at 23:15

1 Answers1

8

In my original question, I thought I was overwriting an existing rule (the left anchor) but actually I was creating a new rule for the left anchor, therefore the conflict and failure to animate.

With the help from @vacawama in the other question about changing AutoLayout rule, it is working now as below:

override func viewDidLoad() {
    super.viewDidLoad()

    let myView = UIView()
    myView.backgroundColor = UIColor.orangeColor()
    myView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(myView)

    myView.topAnchor.constraintEqualToAnchor(view.topAnchor).active = true
    myView.widthAnchor.constraintEqualToAnchor(view.widthAnchor).active = true
    myView.heightAnchor.constraintEqualToAnchor(view.heightAnchor).active = true

    var leftConstraint = myView.leftAnchor.constraintEqualToAnchor(view.rightAnchor)
    leftConstraint?.active = true

    myView.layoutIfNeeded()

    /* try to deactivate a rule and create a new rule, then animate it */
    leftConstraint?.active = false
    leftConstraint = myView.leftAnchor.constraintEqualToAnchor(view.leftAnchor)
    leftConstraint?.active = true

    UIView.animateWithDuration(1.0) { self.view.layoutIfNeeded() }
}

But if I change the last line to call layoutIfNeeded() on myView instead, it's not animating (any comment is welcome). I actually want to call it on a subview instead of a parent view because I don't want all subviews to animate (in a complete use case). So it probably needs some workaround, but the basic concept is there and have solved the original question.

Community
  • 1
  • 1
Joe Huang
  • 6,296
  • 7
  • 48
  • 81