I want to show an animation after the my OnboardingController
with container – Page
with image view is opened. I use this code for to do it, but the animation doesn’t work in my app:
My code in ViewController class:
class ViewController: UIViewController {
lazy var button: UIButton = {
let button = UIButton()
button.backgroundColor = .darkGray
button.translatesAutoresizingMaskIntoConstraints = false
button.addTarget(self, action: #selector(setupViews), for: .touchUpInside)
return button
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(button)
button.frame = CGRect(x: 400, y: 100, width: 100, height: 50)
}
@objc func setupViews() {
let detailController = OnboardingController()
self.present(detailController, animated: true, completion: nil)
}
}
My code in OnboardingController class:
class OnboardingController: UIViewController {
let container: UIView = {
let view = UIView()
view.backgroundColor = .blue
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
let views: Page = {
let view = Page()
view.backgroundColor = .red
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(container)
container.addSubview(views)
container.topAnchor.constraint(equalTo: view.topAnchor, constant: 0.0).isActive = true
container.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0.0).isActive = true
container.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0.0).isActive = true
container.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0.0).isActive = true
views.topAnchor.constraint(equalTo: container.topAnchor).isActive = true
views.bottomAnchor.constraint(equalTo: container.bottomAnchor).isActive = true
views.leadingAnchor.constraint(equalTo: container.leadingAnchor).isActive = true
views.trailingAnchor.constraint(equalTo: container.trailingAnchor).isActive = true
}
}
My code in Page class:
class Page: UIView {
private let imageView: UIImageView = {
let image = UIImageView()
image.image = UIImage(named: "1")
image.translatesAutoresizingMaskIntoConstraints = false
return image
}()
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(imageView)
imageView.topAnchor.constraint(equalTo: topAnchor).isActive = true
imageView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
imageView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: -120).isActive = true
imageView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: 0).isActive = true
self.imageView.transform = CGAffineTransformTranslate(.identity, 0, 0)
UIView.animate(withDuration: 7.0, delay: 0, animations: {
self.imageView.transform = CGAffineTransformTranslate(.identity, 120, 0)
}, completion: nil)
}
required init?(coder: NSCoder) {
fatalError("error")
}
}
How to solve this problem?
2
Answers
Animations will not work in
init
since view is not added to window or view hierarchy yet.Try adding your animation code in
didMoveToSuperview
orlayoutSubviews
. Also if you are usinglayoutSubviews
make sure animations are triggered only once using a flag maybe.Example:
I recommend controlling the animation from its superview life cycle, in this case is
OnboardingController
, andviewDidAppear
is the best option in this situation. It should look like:And manage
Page
state by: