I want my swift code to do a animation with the separate and different actions. That are in sequential order. The first 2 animations work however when I add the 3rd animation it does not work anymore and causes a compile error. You can see the 3rd animation where the comment is. I just want to get all 3 animations to work.
import UIKit
class ViewController: UIViewController {
var block1 = UIView()
var btn = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
[block1,btn].forEach{
$0.translatesAutoresizingMaskIntoConstraints = false
view.addSubview($0)
}
block1.backgroundColor = .yellow
btn.backgroundColor = .red
block1.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height * 0.1)
btn.frame = CGRect(x: 100, y: 300, width: 100, height: 100)
btn.backgroundColor = .red
btn.addTarget(self, action: #selector(diverse), for: .touchDown)
}
@objc func diverse(){
//1
UIView.animate(withDuration: 1, animations: {
self.block1.frame = CGRect(x: 100, y: 100, width: 100, height: 200)
self.block1.center = self.view.center
})
//2
{ done in
if done {
UIView.animate(withDuration: 11, animations: {
self.block1.frame = CGRect(x: 100, y: 100, width: 22, height: 100)
self.block1.center = self.view.center
})
}
}
//3 does not work
{ done in
if done {
UIView.animate(withDuration: 11, animations: {
self.block1.frame = CGRect(x: 100, y: 100, width: 2, height: 100)
self.block1.center = self.view.center
})
}
}
}
}
The documentation for animate(withDuration:animations:completion:)
shows its declaration, which is this:
class func animate(withDuration duration: TimeInterval,
animations: @escaping () -> Void,
completion: ((Bool) -> Void)? = nil)
The completion
argument label takes in a closure, which gets called when the animation finishes.
UIView.animate(withDuration: 1, animations: {
self.block1.frame = CGRect(x: 100, y: 100, width: 100, height: 200)
self.block1.center = self.view.center
}) { done in /// closure here
}
However, there is no argument label for a second completion closure. That is why
UIView.animate(withDuration: 1, animations: {
self.block1.frame = CGRect(x: 100, y: 100, width: 100, height: 200)
self.block1.center = self.view.center
}) { done in /// closure here
} { done in /// second closure? Nope.
}
... does not compile.
Instead, what you want to do is
/// start first animation
UIView.animate(withDuration: 1, animations: {
self.block1.frame = CGRect(x: 100, y: 100, width: 100, height: 200)
self.block1.center = self.view.center
}) { done in
/// first animation finished, start second
if done {
UIView.animate(withDuration: 11, animations: {
self.block1.frame = CGRect(x: 100, y: 100, width: 22, height: 100)
self.block1.center = self.view.center
}) { done in
/// second animation finished, start third
if done {
UIView.animate(withDuration: 11, animations: {
self.block1.frame = CGRect(x: 100, y: 100, width: 2, height: 100)
self.block1.center = self.view.center
})
}
}
}
}