Просмотр анимации с помощью Snapkit

Я пробовал разные уроки для создания легкой анимации с помощью Snapkit, но, похоже, ничего не помогло. Я даже попробовал Spring Framework, но это не сработало. Вот мой код

private func setupMatchView() {
    view.addSubview(matchOverlayView)
    matchOverlayView.snp.makeConstraints { (make) in
        make.top.equalTo(view.safeAreaLayoutGuide.snp.topMargin)
        make.bottom.equalTo(view.safeAreaLayoutGuide.snp.bottomMargin)
        make.left.equalToSuperview()
        make.right.equalToSuperview()
    }
    matchOverlayView.backgroundColor = UIColor.white.withAlphaComponent(0.5)

    view.addSubview(matchView)
    matchView.snp.makeConstraints { (make) in
        make.left.equalToSuperview().offset(32)
        make.right.equalToSuperview().inset(32)
        make.centerX.equalToSuperview()
        make.centerY.equalToSuperview()
    }
    matchView.backgroundColor = .white
    matchView.layer.cornerRadius = 8
    matchView.dropShadow()

    matchView.addSubview(matchYourImageView)
    matchYourImageView.snp.makeConstraints { (make) in
        make.height.width.equalTo(100)
        make.centerX.equalToSuperview().inset(20)
        make.top.equalToSuperview().offset(40)
    }
    matchYourImageView.backgroundColor = UIColor(red:0.77, green:0.77, blue:0.77, alpha:1.00)
    matchYourImageView.layer.cornerRadius = 50
    matchYourImageView.clipsToBounds = true

    matchView.addSubview(matchHerImageView)
    matchHerImageView.snp.makeConstraints { (make) in
        make.height.width.equalTo(100)
        make.centerX.equalToSuperview().inset(-20)
        make.top.equalTo(matchYourImageView.snp.top)
    }
    matchHerImageView.backgroundColor = UIColor(red:0.69, green:0.69, blue:0.69, alpha:1.00)
    matchHerImageView.layer.cornerRadius = 50
    matchHerImageView.clipsToBounds = true

    matchView.addSubview(matchLabel)
    matchLabel.snp.makeConstraints { (make) in
        make.top.equalTo(matchYourImageView.snp.bottom).offset(64)
        make.centerX.equalToSuperview()
    }
    matchLabel.text = "Match"
    matchLabel.font = UIFont.systemFont(ofSize: 28, weight: .heavy)

    matchView.addSubview(matchCTA)
    matchCTA.snp.makeConstraints { (make) in
        make.top.equalTo(matchLabel.snp.bottom).offset(40)
        make.left.equalToSuperview().offset(32)
        make.right.equalToSuperview().inset(32)
        make.height.equalTo(44)
        make.bottom.equalToSuperview().inset(40)
    }
    matchCTA.setTitle("Go To Chat", for: .normal)


    matchView.addSubview(matchCloseButton)
    matchCloseButton.snp.makeConstraints { (make) in
        make.width.equalTo(32)
        make.height.equalTo(32)
        make.right.equalToSuperview().inset(16)
        make.top.equalToSuperview().inset(16)
    }
    matchCloseButton.setImage(UIImage(named: "Close"), for: .normal)
    matchCloseButton.addTarget(self, action: #selector(self.closeButtonTapped(_:)), for:.touchUpInside)

    matchView.layoutIfNeeded()

    hideMatch()
}

@objc func closeButtonTapped(_ sender:UIButton) {
    hideMatch()
}

private func hideMatch() {
    self.matchOverlayView.alpha = 0
    self.matchView.snp.updateConstraints { (make) in
        make.centerY.equalToSuperview().offset(self.view.frame.height)
    }
    UIView.animate(withDuration: 1) {
        self.matchView.layoutIfNeeded()
    }
}
private func showMatch() {
    self.matchOverlayView.alpha = 1
    self.matchView.snp.updateConstraints { (make) in
        make.centerY.equalToSuperview().offset(0)
    }
    UIView.animate(withDuration: 2) {
        self.matchView.layoutIfNeeded()
    }
}

И это не работает. Когда пользователь запускает showMatch() Метод, который просто показывает, нет анимации. Если кто-то может помочь, это будет здорово.

1 ответ

Вы должны позвонить layoutIfNeeded на matchViewсуперсмотр:

private func showMatch() {
    self.matchOverlayView.alpha = 1
    self.matchView.snp.updateConstraints { (make) in
        make.centerY.equalToSuperview().offset(0)
    }
    UIView.animate(withDuration: 2) {
        self.view.layoutIfNeeded()
    }
}

Когда вы звоните layoutIfNeeded на UIView механизм компоновки использует это представление в качестве корневого представления и начинает компоновку всех подпредставлений этого представления. Но только подпункты!

Вот почему изменение макета не анимируется при вызове layoutIfNeeded на matchView, Вы должны позвонить layoutIfNeeded на одном из matchViewSuperviews, чтобы вызвать изменение макета.

Единственный существующий ответ не сработал для меня.
Вот что у меня сработало.

let anim = UIViewPropertyAnimator(duration: 0.2, curve: UIView.AnimationCurve.linear, animations: { [weak self] in
    self?.matchView.snp.remakeConstraints { (make) in
        make.centerY.equalToSuperview().offset(0)
    }
    self?.view.layoutIfNeeded()
})

anim.startAnimation()
Другие вопросы по тегам