iosswiftuikit

How to show animation in another controller?


I want to show an animation after the my view controller with the image view is opened. I use this code for to do it, but the animation doesn't work in my app:

view controller

class ViewController: UIViewController {
    
    lazy var button: UIButton = {
        let button = UIButton()
        button.backgroundColor = .darkGray
        button.translatesAutoresizingMaskIntoConstraints = false
        button.addTarget(self, action: #selector(show), for: .touchUpInside)
        return button
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(button)
        button.frame = CGRect(x: 500, y: 200, width: 100, height: 100)
    }
    
    @objc func show() {
        let detailController = OnboardingController()
        self.present(detailController, animated: true, completion: nil)
    }
    
}

OnboardingController code:

class OnboardingController: UIViewController {
    
    private let imageView: UIImageView = {
        let image = UIImageView()
        image.image = UIImage(named: "1")
        image.translatesAutoresizingMaskIntoConstraints = false
        return image
    }()
        
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.addSubview(imageView)
        
        imageView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        imageView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
        imageView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: -320).isActive = true
        imageView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0).isActive = true
        
        imageView.layer.removeAllAnimations()
        imageView.transform = CGAffineTransformTranslate(.identity, 0, 0)
        
        UIView.animate(withDuration: 1.0, delay: 0, animations: {
            self.imageView.transform = CGAffineTransformTranslate(.identity, 320, 0)
        }, completion: nil)
        
    }
}

How to solve this problem?


Solution

  • You are executing your animation code in viewDidLoad() ... which happens prior to any actual layout.

    Move the animation code to viewDidAppear:

    class OnboardingController: UIViewController {
        
        private let imageView: UIImageView = {
            let image = UIImageView()
            image.image = UIImage(named: "1")
            image.translatesAutoresizingMaskIntoConstraints = false
            return image
        }()
        
        override func viewDidLoad() {
            super.viewDidLoad()
            
            view.addSubview(imageView)
            
            imageView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
            imageView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
            imageView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: -320).isActive = true
            imageView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0).isActive = true
            
        }
        override func viewDidAppear(_ animated: Bool) {
            super.viewDidAppear(animated)
            
            UIView.animate(withDuration: 1.0, delay: 0, animations: {
                self.imageView.transform = CGAffineTransformTranslate(.identity, 320, 0)
            }, completion: nil)
        }
    }