Search code examples
iosswiftxcodenslayoutconstraint

UIView Animation not working with NSLayoutConstraint?


I have a keyboard notification and I want it so that when it goes off, the placeholder view animates to the left edge of the search bar.

Below is what I use to call the animation which is asynchronous with the keyboard opening. Currently, the view moves to the spot I want it to, however it's as if it's teleporting there rather than animating.

        DispatchQueue.main.async {
            if isKeyboardShowing {
                UIView.animate(withDuration: 2, delay: 1, options: UIViewAnimationOptions.curveEaseOut, animations: {
                    NSLayoutConstraint(item: self.placeholder, attribute: .left, relatedBy: .equal, toItem: self.searchBar, attribute: .left, multiplier: 1, constant: 5).isActive = true
                }, completion: { (completed) in

                })

            }
        }

Any Suggestions?


Solution

  • The animation with constraints could be a little bit tricky. First you need to adjust desired constraints, outside of the animation closure:

    NSLayoutConstraint(item: self.placeholder, attribute: .left, relatedBy: .equal, toItem: self.searchBar, attribute: .left, multiplier: 1, constant: 5).isActive = true
    

    Since constraint changes could cause other views change their position, you need ask superview (in the most cases the VC-view) to layout its subviews within the animation closure:

     UIView.animate(withDuration: 2, delay: 1, options: UIViewAnimationOptions.curveEaseOut, animations: {
          self.view.layoutIfNeeded()
     }, completion: nil)
    

    Therefore the superview adjusts subviews positions for you within the animation block.