I am trying to run some sample code from the book Build WatchOS: Develop and Design. The following segment of code returns two errors:
@IBAction func buttonTapped(){
if animating {
spinnerImage.stopAnimating()
animating = false
animateWithDuration(0.2, animations: updateButtonToStopped())
} else {
spinnerImage.startAnimating()
animating = true
animateWithDuration(0.2, animations: updateButtonToGoing())
}
}
Both errors occur in the calls to animateWithDuration() and indicate that there is a type conflict. Any ideas of how I can fix this?
Instead of calling animateWithDuration
like so:
animateWithDuration(0.2, animations: updateButtonToStopped())
you'd like to give it your updateButtonToStopped
function as a parameter like so:
animateWithDuration(0.2, animations: updateButtonToStopped)
Notice that the () after updateButtonToStopped
is gone.
And the same goes for updateButtonToGoing
of course :)
If you look at the documentation for animateWithDuration
, (which you can see the Swift 3 version of here) you can see that the signature looks like this:
func animate(withDuration duration: TimeInterval, animations: @escaping () -> Void)
The animations
is the interesting part here.
() -> Void
means that animations
takes a function, which must contain no parameters and which returns Void
.
In your case you call it like so:
animateWithDuration(0.2, animations: updateButtonToStopped())
But...when you use updateButtonToStopped()
, what you are actually saying is, "call updateButtonToStopped()
and use the output of that for the animations
parameter". This is not what the compiler expects, it expects, as we just saw, a function, taking no parameters and returning Void
.
So when you say:
animateWithDuration(0.2, animations: updateButtonToStopped)
Without the parentheses it means that you do not invoke updateButtonToStopped
, you just pass it to animate
as a parameter.
Hope this helps you.