2

I have a view which I want to move to the center of the main view of the ViewController. I want to do this by using UIView.animateWithDuration. In the completion block of the method I want to add a second view.

Below the code from my ViewController class. I have setup the view in the storyboard and connected it via the Outlet

import UIKit

class ViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.



}


override func viewDidAppear(animated: Bool) {
        animation()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


@IBOutlet weak var card: UIView!



func animation() {
    print("viewCenter  \(self.view.center)")
    print("cardCenter 1 \(self.card.center)")

    UIView.animateWithDuration(1.0,
        delay: 2.0,
        options: UIViewAnimationOptions.CurveLinear,
        animations: { () -> Void in
            self.card.center = self.view.center
            print("number of constraints on card: \(self.card.constraints.count)")
        },
        completion: { finished in
            print("cardCenter 2 \(self.card.center)")

                let rect = CGRect(x: 200, y: 300, width: 50, height: 50)
                let tempView = UIView(frame: rect)
                tempView.backgroundColor = UIColor.blueColor()
                self.view.addSubview(tempView)

                self.view.layoutIfNeeded()

             print("cardCenter 3 \(self.card.center)")
        })
}

}

The animation works fine, until the moment the completion is executed. The first view is shown at its initial place before animation. In the console however the printed coordinates of the center of the view match the center of the main View

Console output

viewCenter  (160.0, 284.0)  
cardCenter 1 (140.0, 92.0)  
cardCenter 2 (160.0, 284.0)  
cardCenter 3 (160.0, 284.0)  

Can anyone explain this behavior when adding a UIView in the completion block?

EDIT

Based on comment of Chris I added some logging on constraints of card and
self.view.layoutIfNeeded() to the completion. Now the console output does show the initial coordinates of the View

New Console Output

viewCenter (160.0, 284.0)
cardCenter 1 (140.0, 92.0)
number of constraints on card: 0
cardCenter 2 (160.0, 284.0)
cardCenter 3 (140.0, 92.0)

Arne
  • 25
  • 6
  • Do you have any constraints applied? – Chris Slowik Sep 29 '15 at 20:29
  • Even if you don't have constraints, you may need to disable autolayout explicitly in your xib. – Logan Sep 29 '15 at 20:38
  • 1
    I am working with size classes that requires auto layout. The point is that I do not understand why de animation work fine without the code in the completion block. But when adding an extra view which has no relation or constraints with the first view, I get these unexpected behavior – Arne Sep 29 '15 at 21:03

1 Answers1

1

If you have constraints in Interface Builder, remove the constraints from card and try again - you'll find that it works as expected.

When animating a view with constraints on it, first update the constraint constant, then inside your animation block, call self.view.layoutIfNeeded(). Animating properties directly will produce unexpected results, as you have seen in your example.

Chris Slowik
  • 2,859
  • 1
  • 14
  • 27
  • 1
    @ Chris, there are no constraints on the view. Just dropped a view in interface builder and dragged an IBOutlet in the controller. The inspector does not show constraints. When setting completion block to nil, the animation works. I agree on the unexpected result part, but I can't find the reason – Arne Sep 29 '15 at 20:44
  • Im still looking at this, its really weird. I can't recall ever seeing this before but playing with your code I'm getting the same results. Will revisit in a bit - in the meantime, if you set your center in the completion block as well, you'll be fine.. Not ideal but it works. – Chris Slowik Sep 29 '15 at 21:12
  • thx for looking into this. I'll use the work around in the meantime, but it looks weird...... – Arne Sep 30 '15 at 10:46