Search code examples
iosswiftnslayoutconstraintuiviewanimation

Swift iOS -Constraint isn't animating even though view.layoutIfNeeded() is called


I have a rounded likeButton that is behind a rounded moreButton. The likeButton is pinned to the centerX and centerY of the moreButton. When I press the moreButton I want to animate the likeButton 200 points above the moreButton.

I use a NSLayoutConstraint to keep track of the likeButton's centerY and to make changes to it. When I call UIView.animate and inside it's closure I call self.view.layoutIfNeeded() the view isn't updating.

@objc func moreButtonTapped(){

    likeButtonCenterY?.isActive = false
    likeButton.centerYAnchor.constraint(equalTo: self.moreButton.centerYAnchor, constant: -200)
    likeButtonCenterY?.isActive = true

    UIView.animate(withDuration: 0.3) {
        self.view.layoutIfNeeded()
    }
}

Where am I going wrong?

let moreButton: UIButton = {
    let button = UIButton(type: .system)
    button.translatesAutoresizingMaskIntoConstraints = false
    button.setImage(UIImage(named: "more"), for: .normal)
    button.tintColor = .red
    button.clipsToBounds = true
    button.addTarget(self, action: #selector(moreButtonTapped), for: .touchUpInside)
    return button
}()

let likeButton: UIButton = {
    let button = UIButton(type: .system)
    button.translatesAutoresizingMaskIntoConstraints = false
    button.setImage(UIImage(named: "like"), for: .normal)
    button.tintColor = .blue
    button.clipsToBounds = true
    return button
}()

var likeButtonCenterY: NSLayoutConstraint?

override func viewDidLoad() {
    super.viewDidLoad()
    view.backgroundColor = .white
    setAnchors()
}

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    moreButton.layer.cornerRadius = moreButton.frame.size.width / 2
    likeButton.layer.cornerRadius = likeButton.frame.size.width / 2
}

@objc func moreButtonTapped(){

    likeButtonCenterY?.isActive = false
    likeButton.centerYAnchor.constraint(equalTo: self.moreButton.centerYAnchor, constant: -200)
    likeButtonCenterY?.isActive = true

    UIView.animate(withDuration: 0.3) {
        self.view.layoutIfNeeded()
    }
}

func setAnchors(){
    view.addSubview(likeButton)
    view.addSubview(moreButton)

    moreButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    moreButton.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -200).isActive = true
    moreButton.widthAnchor.constraint(equalToConstant: 100).isActive = true
    moreButton.heightAnchor.constraint(equalToConstant: 100).isActive = true

    likeButtonCenterY = likeButton.centerYAnchor.constraint(equalTo: moreButton.centerYAnchor)
    likeButtonCenterY?.isActive = true

    likeButton.centerXAnchor.constraint(equalTo: moreButton.centerXAnchor).isActive = true
    likeButton.widthAnchor.constraint(equalToConstant: 100).isActive = true
    likeButton.heightAnchor.constraint(equalToConstant: 100).isActive = true
}

Solution

  • Try this

    @objc func moreButtonTapped(){
    
    likeButtonCenterY?.isActive = false
    likeButtonCenterY = likeButton.centerYAnchor.constraint(equalTo: self.moreButton.centerYAnchor, constant: -200)
    likeButtonCenterY?.isActive = true
    
    UIView.animate(withDuration: 0.3) {
        self.view.layoutIfNeeded()
    }
    }
    

    You have forgotten to write likeButtonCenterY =