jtrivedi / Wave

Wave is a spring-based animation engine for iOS and macOS that makes it easy to create fluid, interruptible animations that feel great.

Home Page:https://jtrivedi.github.io/Wave/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Animation broken on UIViewControllerAnimatedTransitioning

alfredcc opened this issue · comments

commented

Hi jtrivedi,
Thanks for sharing. I find some trouble when using Wave with UIViewControllerAnimatedTransitioning
This code works fine with UIView.animation.

import UIKit
import Wave

class PopupViewController: UIViewController {
    lazy var contentView: UIView = {
        let view = UIView()
        view.backgroundColor = .white
        view.layer.cornerRadius = 10
        view.layer.masksToBounds = true
        view.alpha = 0
        view.transform = .init(scaleX: 0, y: 0)
        return view
    }()

    lazy var blurEffectView: UIVisualEffectView = {
        let blurEffect = UIBlurEffect(style: .dark)
        let blurEffectView = UIVisualEffectView(effect: blurEffect)
        blurEffectView.frame = view.bounds
        blurEffectView.alpha = 0.0
        return blurEffectView
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        setupViews()
    }

    @objc func viewTapped() {
        dismiss(animated: true)
    }

    private func setupViews() {
        view.backgroundColor = .clear

        blurEffectView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(viewTapped)))

        view.addSubview(blurEffectView)

        view.addSubview(contentView)
        contentView.snp.makeConstraints { make in
            make.center.equalToSuperview()
            make.leading.equalToSuperview().offset(20)
            make.trailing.equalToSuperview().offset(-20)
            make.height.equalTo(400)
        }
    }
}

final class TransitionManager:
    NSObject,
    UIViewControllerTransitioningDelegate,
    UIViewControllerAnimatedTransitioning
{
    private let transitionDuration: TimeInterval = 0.6

    let interactiveTransition = UIPercentDrivenInteractiveTransition()

    func transitionDuration(using _: UIViewControllerContextTransitioning?) -> TimeInterval {
        transitionDuration
    }

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        let containerView = transitionContext.containerView
        if let toViewController = transitionContext.viewController(forKey: .to) as? PopupViewController {
            containerView.addSubview(toViewController.view)
            toViewController.contentView.center.y -= containerView.bounds.size.height
            
            let animatedSpring = Spring(dampingRatio: 0.68, response: transitionDuration)
            Wave.animate(withSpring: animatedSpring) {
                toViewController.blurEffectView.alpha = 1
                toViewController.contentView.alpha = 1
                toViewController.contentView.transform = .identity
                toViewController.contentView.center.y += containerView.bounds.size.height
            } completion: { _,_  in
                transitionContext.completeTransition(true)
            }

        } else if let fromViewController = transitionContext.viewController(forKey: .from) as? PopupViewController {
            containerView.addSubview(fromViewController.view)
            let animatedSpring = Spring(dampingRatio: 0.68, response: transitionDuration)
            Wave.animate(withSpring: animatedSpring) {
                fromViewController.blurEffectView.alpha = 0
                fromViewController.contentView.center.y -= containerView.bounds.size.height
                fromViewController.contentView.transform = CGAffineTransform(scaleX: 0.1, y: 0.1)
            } completion: { _,_  in
                transitionContext.completeTransition(true)
            }
        }
    }

    func animationController(forPresented _: UIViewController, presenting _: UIViewController, source _: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return self
    }

    func animationController(forDismissed _: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return self
    }
}
class ViewController: UIViewController {
    ...
    ...
    private let transition = TransitionManager()
    let viewController = PopupViewController()
    viewController.modalPresentationStyle = .custom
    viewController.transitioningDelegate = transition
    present(viewController, animated: true, completion: nil)
    ...
    ...
}

Hey there. I haven’t run your code, but when animating view properties with Wave, you need to do ‘view.animator.alpha = 1’, not ‘view.alpha = 1’.

Without setting the property on the view’s animator, Wave won’t pick up the animation.

Let me know if that fixes it!