Dillion / iOS-Flip-Transform

Core Animation framework for navigating data by flipping
919 stars 155 forks source link

Previous view flickers #2

Closed tobe-sta closed 12 years ago

tobe-sta commented 12 years ago

I have a sequence controlled, forward direction flipView. When I change the flipView, at the end of the animation, it flickers the previous view that I was just on. I notice it occasionally happens on your demo app too. Is there a way to prevent that from happening?

Thanks for any help.

Dillion commented 12 years ago

Yes I've also noticed some flickering, it appears more serious on the simulator and on older devices. I'm not very sure what is the exact cause, but likely due to one or more of the below:

  1. z-index crossing when I reset the perspective transform
  2. view reverting to its original state (showing the untransformed view for a split second) at the end of the animation loop
  3. incorrect usage of CAMediaTiming fillmode in the animation loop (theoretically fill mode both and forwards are supposed to freeze the transform values at the end of the animation loop)
  4. incorrect usage of CATransaction to reset the animation atomically

The problems should be contained within AnimationDelegate source file, the type of flip animation doesn't matter. I hope to release an update soon to fix the issue (probably going to try switching to GCD for the animation loop), in the meantime you can try editing the AnimationDelegate file

DaveBatton commented 12 years ago

You should be able to fix the flicker by using one or (probably) both of these lines of code:

animation.fillMode = kCAFillModeForwards;
animation.removedOnCompletion = NO;

This will freeze the final animation until you're able to update the underlying views to the new values. Don't forget the remove the animation in the -animationDidStop:finished: callback if you set the -removedOnCompletion flag.

Let me know if you need help getting this working.

tobe-sta commented 12 years ago

Where exactly do you put those two lines? I played around with them in AnimationDelegate, but with no success.

Dillion commented 12 years ago

@tobe-sta the wrapper function - (void)setTransformProgress:::::::::: in AnimationDelegate allows you to specify the fillMode and removedOnCompletion setting, currently all the animations (except for the queued shadow animation in triggered/auto mode) uses kCAFillModeForwards and removedOnCompletion = NO

@DaveBatton I think the flickering is due to the removal of animation after completion, whether manually after the callback from animation stopping, or from the removedOnCompletion property. The logic for my animation loop is -

  1. add transform animation when input is received
  2. remove animation when animation ends or interrupted by new input (for controlled mode)
  3. if not at resting position, move to nearest resting position (for controlled mode)
  4. remove animation when animation ends
  5. rearrange layers according to whether the flip has progressed or is still on the same frame

For all the areas where the animation is removed, the update has to be committed atomically so that the intermediate changes are not visible. In particular, for the last operation because rearrangement of layers is involved, the rearrangement has to be committed together with the animation removal so that the layer that just completes animating does not show its original state before being replaced by the next layer

I've updated the code to reflect this, let me know if it fixes the issue

tobe-sta commented 12 years ago

That did the trick @Dillion! No flickering at all, I wish I could code like that.

Thanks a lot!