代码之家  ›  专栏  ›  技术社区  ›  Florian Ldt

使用SnapKit的约束动画

  •  8
  • Florian Ldt  · 技术社区  · 7 年前

    我正在尝试使用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
        }()
    
        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")
        }
    
    }
    

    我尝试制作的两个视图是leftAvatarBg和rightAvatarBg。

    在制作动画之前,我将它们设置在屏幕的外部,希望让它们在一个视图中从左向右滑动,在另一个视图中从右向左滑动。

    在我的控制器中,我只需调用:

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

    这样做的结果是,整个视图正在设置动画(缩放)。

    enter image description here

    我错过什么了吗?

    更新:得益于swift2geek,它们似乎是对象创建和动画之间的冲突。在他的解决方案中,他通过按下按钮触发动画。在我的例子中,我希望尽快自动触发动画。如何确保在创建对象后启动动画?

    2 回复  |  直到 7 年前
        1
  •  11
  •   Matvii Hodovaniuk swift2geek    5 年前

    我对你的bdsm SnapKit不太在行,所以你要自己设定正确的约束条件。所以它不起作用的主要原因是——你应该将动画和对象创建分开。

    您的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()
        }
    }
    

    你的MatchAnimation课程:

    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")
        }
    
    }
    

    和匹配按钮:

    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")
        }
    
    }
    
        2
  •  0
  •   sɐunıɔןɐqɐp Zmey    4 年前

    如果希望动画尽快启动,只需添加布局即可 animate() 作用于 viewDidAppear .

    推荐文章