Constraint animation with SnapKit

10,744

im not good with your bdsm SnapKit, so put the right constraints on your own. So the main reason its not working - you should separate animation and object creation.

your viewcontroller:

import UIKit

class ViewController: UIViewController {

    @IBOutlet var matchButton: MatchButton!
    @IBOutlet var matchView: MatchAnimation!

    override func viewDidLoad() {
        super.viewDidLoad()

        setupAnimation()
        setupButton()
    }

    func setupAnimation() {
        matchView = MatchAnimation()
        matchView.isUserInteractionEnabled = true
        view.addSubview(matchView)

    }

    func setupButton() {
        matchButton = MatchButton()
        matchButton.isUserInteractionEnabled = true
        matchButton.isEnabled = true
        matchButton.addTarget(self, action: #selector(pressed(_:)), for: .touchUpInside)

        matchView.addSubview(matchButton)
    }

    @objc func pressed(_ sender: MatchButton!) {
        print("button tapped")
        matchView.animate()
    }
}

your MatchAnimation class:

import UIKit
import SnapKit

class MatchAnimation: UIView {

    let viewBackground: UIView = {
        let view = UIView()
        view.backgroundColor = UIColor(red: 0/255, green: 0/255, blue: 0/255, alpha: 0.75)
        view.alpha = 1
        return view
    }()

    let matchView: UIView = {
        let view = UIView()
        return view
    }()

    let matchLabel: UILabel = {
        let label = UILabel()
        label.text = "Title"
        label.textColor = .white
        label.textAlignment = .center
        return label
    }()

    let leftAvatarBg: UIView = {
        let view = UIView()
        view.backgroundColor = .white
        view.layer.cornerRadius = 91/2
        return view
    }()

    let rightAvatarBg: UIView = {
        let view = UIView()
        view.backgroundColor = .blue
        view.layer.cornerRadius = 91/2
        return view
    }()

    init() {
        super.init(frame: UIScreen.main.bounds)
        viewBackground.frame = self.frame
        self.addSubview(viewBackground)

        self.addSubview(matchView)
        matchView.addSubview(matchLabel)
        matchView.addSubview(leftAvatarBg)
        matchView.addSubview(rightAvatarBg)

        matchView.snp.makeConstraints { (make) in
            make.left.right.equalToSuperview()
            make.center.equalToSuperview()
        }

        matchLabel.snp.makeConstraints { (make) in
            make.top.equalToSuperview()
            make.centerX.equalToSuperview()
            make.size.equalTo(CGSize(width: 193, height: 40))
        }

        leftAvatarBg.snp.makeConstraints { (make) in
            make.top.equalTo(matchLabel.snp.bottom).offset(20)
            make.centerX.equalToSuperview()
            make.size.equalTo(CGSize(width: 91, height: 91))
            make.right.equalTo(self.snp.left).offset(90)
        }

        rightAvatarBg.snp.makeConstraints { (make) in
            make.top.equalTo(leftAvatarBg)
            make.size.equalTo(leftAvatarBg)
            make.left.equalTo(self.snp.right).inset(120)
        }
    }

    func animate() {

        UIView.animate(withDuration: 5) {
            self.leftAvatarBg.snp.updateConstraints { (make) in
                make.right.equalTo(self.snp.left).offset(UIScreen.main.bounds.width/2+30)
            }

            self.rightAvatarBg.snp.updateConstraints { (make) in
                make.left.equalTo(self.snp.right).inset(UIScreen.main.bounds.width/2+30)
            }
            self.layoutIfNeeded()
        }
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

and MatchButton:

import UIKit
import SnapKit

class MatchButton: UIButton {

    let goToChatButton: UIButton = {
        let button = UIButton()
        button.setTitle("Button", for: .normal)
        button.backgroundColor = .red
        button.setTitleColor(.white, for: .normal)
        button.layer.cornerRadius = 24.5
        return button
    }()

    init() {
        super.init(frame: UIScreen.main.bounds)

        self.addSubview(goToChatButton)

        goToChatButton.snp.makeConstraints { (make) in
            make.size.equalTo(CGSize(width: 171, height: 50))
            make.top.greaterThanOrEqualTo(100)
            make.centerX.equalToSuperview()

        }
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}
Share:
10,744

Related videos on Youtube

Florian Ldt
Author by

Florian Ldt

Updated on September 14, 2022

Comments

  • Florian Ldt
    Florian Ldt over 1 year

    I am trying to implement the animation of 2 views using SnapKit.

    Here is my Animation view:

    class MatchAnimation: UIView {
    
        let viewBackground: UIView = {
            let view = UIView()
            view.backgroundColor = UIColor(red: 0/255, green: 0/255, blue: 0/255, alpha: 0.75)
            view.alpha = 1
            return view
        }()
    
        let matchView: UIView = {
            let view = UIView()
            return view
        }()
    
        let matchLabel: UILabel = {
            let label = UILabel()
            label.text = "Title"
            label.textColor = .white
            label.textAlignment = .center
            return label
        }()
    
        let leftAvatarBg: UIView = {
            let view = UIView()
            view.backgroundColor = .white
            view.layer.cornerRadius = 91/2
            return view
        }()
    
        let rightAvatarBg: UIView = {
            let view = UIView()
            view.backgroundColor = .blue
            view.layer.cornerRadius = 91/2
            return view
        }()
    
        let goToChatButton: UIButton = {
            let button = UIButton()
            button.setTitle("Button", for: .normal)
            button.backgroundColor = .red
            button.setTitleColor(.white, for: .normal)
            button.layer.cornerRadius = 24.5
            return button
        }()
    
        init() {
            super.init(frame: UIScreen.main.bounds)
            viewBackground.frame = self.frame
            self.addSubview(viewBackground)
    
            self.addSubview(matchView)
            matchView.addSubview(matchLabel)
            matchView.addSubview(leftAvatarBg)
            matchView.addSubview(rightAvatarBg)
            matchView.addSubview(goToChatButton)
    
            matchView.snp.makeConstraints { (make) in
                make.left.right.equalToSuperview()
                make.center.equalToSuperview()
            }
    
            matchLabel.snp.makeConstraints { (make) in
                make.top.equalToSuperview()
                make.centerX.equalToSuperview()
                make.size.equalTo(CGSize(width: 193, height: 40))
            }
    
            leftAvatarBg.snp.makeConstraints { (make) in
                make.top.equalTo(matchLabel.snp.bottom).offset(20)
                make.size.equalTo(CGSize(width: 91, height: 91))
                make.right.equalTo(self.snp.left).offset(0)
            }
    
            rightAvatarBg.snp.makeConstraints { (make) in
                make.top.equalTo(leftAvatarBg)
                make.size.equalTo(leftAvatarBg)
                make.left.equalTo(self.snp.right).inset(0)
            }
    
            goToChatButton.snp.makeConstraints { (make) in
                make.size.equalTo(CGSize(width: 171, height: 50))
                make.top.equalTo(leftAvatarBg.snp.bottom).offset(25)
                make.centerX.equalToSuperview()
                make.bottom.equalToSuperview()
            }
    
        }
    
        func animate() {
    
    
            UIView.animate(withDuration: 5) {
                self.leftAvatarBg.snp.updateConstraints { (make) in
                    make.right.equalTo(self.snp.left).offset(UIScreen.main.bounds.width/2+30)
                }
    
                self.rightAvatarBg.snp.updateConstraints { (make) in
                    make.left.equalTo(self.snp.right).inset(UIScreen.main.bounds.width/2+30)
                }
                self.layoutIfNeeded()
            }
        }
    
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    
    }
    

    The 2 views I tried to animate are leftAvatarBg and rightAvatarBg.

    Before the animation, I set them at the exterior of the screen and want to make them slide from left to right for one view and from right to left for the other.

    In my controller, I just call:

    func setupAnimation() {
        let matchView = MatchAnimation()
         view.addSubview(matchView)
         matchView.animate()
    }
    

    The result of this is that the entire view is animating (scaling).

    enter image description here

    Did I miss something?

    UPDATE: Thanks to swift2geek, it seems that they is a conflict between the creation of the object and the animation. In his solution, he trigger the animation by pressing a button. In my case, I want to trigger the animation as soon as possible and automatically. How can I ensure that the animation will be fired after the creation of the object ?

  • Florian Ldt
    Florian Ldt almost 6 years
    ty for your answer. You seem to have right, there is a conflict between the animation and the creation of the view. I tried your solution and it works. The problem is I don't want to trigger the animation by pressing a button but as soon as possible and automatically. How can I obtain this ? I have updated my question