Search code examples
iosswiftnslayoutconstraint

View jumps before second animation


I'm trying to animate a table view to appear like a drop-down menu the view appears ok (although I prefer if appeared from top down, currently from middle out) the issue is when I tap the button to close it again the table view jumps then disappears then pressing the button does nothing at all after that. I get constraint errors to after tapping the button a second time.

This is what's called on button tap:

    let height: CGFloat = tableViewOpen ? 0 : 300

    UIViewPropertyAnimator(duration: 0.5, curve: .linear, animations: {
        self.tableView.set(height: height)
        self.tableView.layoutIfNeeded()
    }).startAnimation()

    tableViewOpen = !tableViewOpen

My constraints for the tableView are set using some extensions from the company I work for but look like this:

 tableView.pin(.top, to: .bottom, of: breedButton)
 tableView.pin(toSuperview: [.leading, .trailing])
 tableView.set(width: 250)

More details - The table view is within a child viewcontroller that is just the breed button and table view. The child viewcontrollers constraints are set as follows:

    filterViewController.view.pin(.top, to: .top, of: titleLabel)
    filterViewController.view.pin(toSuperview: .leading)
    filterViewController.view.set(width: 250)

There is no height set for the tableview or childVC, not sure if this is the issue.

Constraint errors after the second button tap:

(
    "<NSLayoutConstraint:0x600003e53a20 UITableView:0x7fe090829000.height == 300   (active)>",
    "<NSLayoutConstraint:0x600003e2c050 UITableView:0x7fe090829000.height == 0   (active)>"
)

Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x600003e53a20 UITableView:0x7fe090829000.height == 300   (active)>

enter image description here


Solution

  • The issue is clear you set a height constraint every button click here

     self.tableView.set(height: height)
    

    but you should create the height constraint once with

    var tableHeight:NSLayoutConstraint!
    

    And set it in viewDidLoad , Then change it's constant like

    tableHeight.constant = show ? 300 : 0 
     UIViewPropertyAnimator(duration: 0.5, curve: .linear, animations: { 
         self.view.layoutIfNeeded()
     }).startAnimation()