0

I'm attempting to write a function that will flash a view's background color to white then back to it's original color. What I have is:

func flashView(view: UIView) {
    var sema = dispatch_semaphore_create(0)
    var color = view.backgroundColor
    println("Animating")
    UIView.animateWithDuration(0.5, animations: { view.backgroundColor = UIColor.whiteColor() }) {
        (success: Bool) in
        println("First block completion")
        UIView.animateWithDuration(0.5, animations: { view.backgroundColor = color }) {
            (success: Bool) in
            println("Nested block completion")
            dispatch_semaphore_signal(sema)
        }
    }
    println("Waiting")
    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER)
    println("Returning")
}

Now, what I'm experiencing is that the Animating message will display followed by the Waiting. The first animateWithDuration block never gets executed (and needless to say the nested one does not either. However, according to Apple's own documentation the UIView.animateWithDuration occurs on a separate thread. So, my understanding, is that the semaphore should wait, the animateWithDuration should complete on a separate thread, and the function should return (after waiting on the semaphore that's signaled in the nested closure). What am I misunderstanding?

Thanks!

Sam Youtsey
  • 856
  • 2
  • 12
  • 32

1 Answers1

2

Animation block executes in main thread, and your dispatch_semaphore_wait blocks main thread. So animation block never executes.

This is one solution.

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { () -> Void in
        dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER)
        println("Returning")
    })

other solutions are here:
How do I wait for an asynchronously dispatched block to finish?

Community
  • 1
  • 1
bluedome
  • 2,330
  • 1
  • 20
  • 16
  • Apple's documentation (from the link in the original question) explicitly says new threads are spun up to complete the animation: `When this code executes, the specified animations are started immediately on another thread so as to avoid blocking the current thread or your application’s main thread.` – Sam Youtsey Dec 04 '14 at 15:59
  • I think Apple says that animation blocks execute asynchronously not to prevent main thread. This does not mean that animations execute in sub thread. You can check the thread in which a code executes by "NSThread.isMainThread()". – bluedome Dec 05 '14 at 05:32