Search code examples
iosswiftuiviewanimationcgaffinetransform

CGAffineTransform not animating within animation block


I am trying to get a view to increase its scale with a spring to it when it appears (using the loadResultsView() function below), but whenever I run this, no animation occurs. The view just ends up in the result state defined in the animation block. I have tried using frame values instead of constraints on the view and the same thing occurs. Why would this be happening?

class ResultsModalViewController: UIViewController {

    let resultsView: ResultsView = {
        let nibArray = Bundle.main.loadNibNamed("ResultsView", owner: self, options: nil)
        let resultsView = nibArray?.first as! ResultsView

        resultsView.restaurant = YelpSearchController.shared.pickRandomRestaurant()

        resultsView.translatesAutoresizingMaskIntoConstraints = false

        resultsView.layer.cornerRadius = 5

        return resultsView
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 0.30)

        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(bgViewTapped))
        view.addGestureRecognizer(tapGestureRecognizer)


        loadResultsView()
    }

    func loadResultsView() {

        self.view.addSubview(resultsView)

        self.resultsView.transform = CGAffineTransform(scaleX: 0.5, y: 0.5)

        UIView.animate(withDuration: 5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 1, options: .curveEaseOut, animations: {

            self.resultsView.transform = CGAffineTransform.identity
        })

        NSLayoutConstraint.activate([
            resultsView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            resultsView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor),
            resultsView.widthAnchor.constraint(equalToConstant: 300)
            ])
    }

    @objc func bgViewTapped() {
        dismiss(animated: true, completion: nil)
    }

}

Solution

  • This was resolved by putting the loadResultsView() into the viewWillAppear() method instead of viewDidLoad(). Thanks to @Koen for pointing out that viewDidLoad() is called before the view appears.

    class ResultsModalViewController: UIViewController {
    
        let resultsView: ResultsView = {
            let nibArray = Bundle.main.loadNibNamed("ResultsView", owner: self, options: nil)
            let resultsView = nibArray?.first as! ResultsView
    
            resultsView.restaurant = YelpSearchController.shared.pickRandomRestaurant()
    
            resultsView.translatesAutoresizingMaskIntoConstraints = false
    
            resultsView.layer.cornerRadius = 5
    
            return resultsView
        }()
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(bgViewTapped))
            view.addGestureRecognizer(tapGestureRecognizer)
    
        }
    
        override func viewWillAppear(_ animated: Bool) {
            super.viewWillAppear(animated)
    
            view.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 0.30)
            loadResultsView()
        }
    
        func loadResultsView() {
    
            self.view.addSubview(resultsView)
    
            self.resultsView.transform = CGAffineTransform(scaleX: 0.5, y: 0.5)
    
            UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
    
                self.resultsView.transform = CGAffineTransform.identity
            })
    
            NSLayoutConstraint.activate([
                resultsView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
                resultsView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor),
                resultsView.widthAnchor.constraint(equalToConstant: 300)
                ])
        }
    
        @objc func bgViewTapped() {
            dismiss(animated: true, completion: nil)
        }
    
    }