Search code examples
swiftapple-watchwatchos-2

Build WatchOS Apps: Develop and Design


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?


Solution

  • In a hurry?

    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 :)

    Why?

    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.