Switch, case, animate: animate(withDuration:)
Switch, case, animate: animate(withDuration:) 관련
The currentAnimation
property can have a value between 0 and 7, each one triggering a different animation. We're going to create a big switch/case
block inside tapped()
, but we're going to start small and work our way up – the default
case will handle any values we don't explicitly catch.
This switch/case statement is going to go inside a new method of the UIView
class called animate(withDuration:)
, which is a kind of method you haven't seen before because it actually accepts two closures. The parameters we'll be using are how long to animate for, how long to pause before the animation starts, any options you want to provide, what animations to execute, and finally a closure that will execute when the animation finishes.
Update your tapped()
method to this:
@IBAction func tapped(_ sender: UIButton) {
sender.isHidden = true
UIView.animate(withDuration: 1, delay: 0, options: [],
animations: {
switch self.currentAnimation {
case 0:
break
default:
break
}
}) { finished in
sender.isHidden = false
}
currentAnimation += 1
if currentAnimation > 7 {
currentAnimation = 0
}
}
Note
Because we want to show and hide the “Tap” button, we need to make the sender
parameter to that method be a UIButton
rather than Any
.
All that code won't do anything yet, which is remarkable given that it's quite a lot! However, it has put us in a position where we can start dabbling with animations. But first, here's a breakdown of the code:
- When the method begins, we hide the
sender
button so that our animations don't collide; it gets unhidden in the completion closure of the animation. - We call
animate(withDuration:)
with a duration of 1 second, no delay, and no interesting options. - For the
animations
closure we don’t need to use[weak self]
because there’s no risk of strong reference cycles here – the closures passed toanimate(withDuration:)
method will be used once then thrown away. - We switch using the value of
self.currentAnimation
. We need to useself
to make the closure capture clear, remember. Thisswitch/case
does nothing yet, because both possible cases just callbreak
. - We use trailing closure syntax to provide our completion closure. This will be called when the animation completes, and its
finished
value will be true if the animations completed fully. - As I said, the completion closure unhides the
sender
button so it can be tapped again. - After the
animate(withDuration:)
call, we have the old code to modify and wrapcurrentAnimation
.
If you run the app now and tap the button, you'll notice it doesn't actually hide and show as you might expect. This is because UIKit detects that no animation has taken place, so it calls the completion closure straight away.