Search code examples
swiftanimationautolayoutnslayoutconstraint

Animate view by changing constraint constant


I have a datePicker that I want to animate in and out of view from the bottom by changing its' top constraint to the super view top.

I have an IBOutlet set to it and on viewDidLoad I'm allowed to change the constraint constant.

enter image description here

  override func viewDidLoad() {
    super.viewDidLoad()
    self.datePickerTopConstraint.constant = self.view.frame.size.height // I can set this to whatever and it will persist
  }

However via an IBAction I try to set the constant to another value and that doesn't persist.

@IBAction func showDatePicker() {
    UIView.animateWithDuration(0.25, animations: {
      () -> Void in
      self.datePickerTopConstraint.constant = self.view.frame.size.height - self.datePicker.frame.size.height // Doesn't persist
      self.view.layoutIfNeeded()
    })
  }

It seems that I can reverse this and have the datePicker appear in view (in viewDidLoad) and animate it out of view, but not have the datePicker appear out of view (like in the example above) and animate inside the view. What have I missed?

EDIT

By setting the top constraint constant to the super view's height I (for some reason I don't understand) also set the date picker's height to 0 which in turn makes the subtraction in showDatePicker pointless.


Solution

  • Restructure the code so that in the button's method work's by first working out the constant's new value and then calling the animation. Pull the height calculation in to it's own function. I think that self.datePicker.frame.size.height does not exist and results in 0, but I would check this using the debugger.

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        datePickerTopConstraint.constant = constantForDatePickerViewHeightConstraint()
        view.setNeedsLayout()
    
    }
    
    
    @IBAction func showDatePicker(button: UIButton) {
    
        // Check constraint constant
        if datePickerTopConstraint.constant == self.view.frame.size.height {
    
            // Date picker is NOT visible
            datePickerTopConstraint.constant = constantForDatePickerViewHeightConstraint()
    
        } else {
            // Date picker is visible
            datePickerTopConstraint.constant = self.view.frame.size.height
        }
    
    
        UIView.animateWithDuration(0.25,
            animations: {() -> Void in
            self.view.layoutIfNeeded()
        })
    }
    
    private func constantForDateOPickerViewHeightConstraint() -> CGFloat {
    
        var value : CGFloat = 200.0
    
        // Workout value you want to as the constant for the constraint.
    
        return value
    }