Screen blinks black in LogoReveal

Hi there,
the application LogoReveal from chapter 23 seems to have an issue. When starting the interactive transition by sliding and stopping before hitting the 50 percent mark, the transition gets cancelled as expected. But the screen turns black for the blink of an eye.

This happens for me on the simulator as well as on the phone.

Is there a way to get around that?

Thanks.

Best,
Sven

Hi Sven,

I have the same problem. Did you ever find a solution? As a quick fix I did this in the RevealAnimator class:

    switch recognizer.state {
    case .changed:
        update(progress)
    case .cancelled, .ended:
        interactive = false
        let transitionLayer = storedContext!.containerView.layer
        transitionLayer.beginTime = CACurrentMediaTime()
        if progress < 0.5 {
            cancel()
            if progress > 0.05 {
                transitionLayer.speed = -0.9
            } else {
                transitionLayer.speed = -0.5
            }
        } else {
            transitionLayer.speed = 1.0
            finish()
        }
    default:
        break
    }

Just experimenting with the transitionLayer speed seemed to stop that black screen. I’m not sure why. But I feel like there’s a better way than this. I’m just not sure how.

Thanks,
Eric

I’m also having this issue with the project. I seem to be able to mitigate the effect in the same way that Eric did, by adjusting the speed of the transition layer and the completionSpeed of the RevealAnimator object. This doesn’t completely fix the issue though, and I’d be interested if anyone else has come up with a more complete solution. It seems like it might be a runloop issue, but I haven’t been able to pin it down.

Thanks,
Jon

Hi all -
I’m not sure if this issue is still important to anyone, but I believe that I’ve found the reason that it’s has this blink. I noticed that by changing the layer speed, I could sometimes get the blink to diminish in frequency on the simulator - however, when I tested on a physical device, I noticed that blink would happen much more consistently, which was frustrating. It also feels fairly ‘hacky’ to specify arbitrary animation layer speeds to resolve an issue that seems more fundamental to the process.

After a lot of experimentation and testing, I reached a couple of conclusions. It seems that we get that blink when relying on the animationDidStop CALayerAnimation delegate method to tell the transitionContext to finish the animation. We are forced to use this delegate method since layer animations have no built in completion handlers, but this delegate method doesn’t get called until just after the animation finished; this results in a perceptible gap between the completion of the animation and the completion message being sent to the transition context. I actually reproduced this behavior in a small sample app just to test this hypothesis, and I again had the blinking screen when relying on layer animations to carry out the view controller transition.

In terms of solutions that don’t involve arbitrary layer speeds, I found a couple. The first feels equally ‘hacky’ - calling performSelector(afterDelay... with a delay of the duration property. This circumvents the control the user has over the animation, so this probably wouldn’t work for interactive view controller transitions.

The other solution that I found was to rely on layer animations for most of the transition, but instead of animating the opacity using a layer animation, I used animate(withDuration... to animate the alpha of the view as needed, and then I used the completion handler of this view animation to send the completion message to the transitionContext. It seems that the transitionContext handles the message from a completion handler as we would normally expect, and the blinking behavior was eliminated.

It seems that, as a general rule, relying on the animationDidStop delegate method to complete the transitionContext transition will result in somewhat undefined behavior (please do correct me if I’m wrong here :slight_smile: )

I haven’t tested this with the UIPercentDrivenTransitionAnimation, but I believe the principle still holds, as I reproduced the blinking behavior using a non-interruptible layer driven transition animation in a separate application.

Anyways - just thought I’d share my findings with anyone else having a similar issue. It was pretty frustrating to deal with, and there wasn’t terribly much assistance online that I could find.

Thanks!
Jon