Coder Social home page Coder Social logo

Comments (16)

MrAlek avatar MrAlek commented on July 22, 2024

This only happens in the simulator, never on a real device, at least for me.

from awpercentdriveninteractivetransition.

MrAlek avatar MrAlek commented on July 22, 2024

Closing issue since I can't reproduce it and haven't got more reports on it.

from awpercentdriveninteractivetransition.

BodaciousPie avatar BodaciousPie commented on July 22, 2024

Hi Alek, I'm experiencing this issue as well. If I put a breakpoint before [transitionContext completeTransition:] I see the toView momentarily before it vanishes.

EDIT: happening on my iPhone 6

from awpercentdriveninteractivetransition.

MrAlek avatar MrAlek commented on July 22, 2024

Wierd, I'll have a look at it. Thanks for the report!

from awpercentdriveninteractivetransition.

Antowkos avatar Antowkos commented on July 22, 2024

Hi! I'm experiencing this issue too. It's reproduce even in your example if you will start dragging in some way (for example, left to right) and then you will try to drag to other way (from right to left). And when you will release finger (cancel will call) - flickering appear.

Also it can be reproduced by starting dragging, then hold for some time (about 1 second or more) and then release finger.

from awpercentdriveninteractivetransition.

MrAlek avatar MrAlek commented on July 22, 2024

Yeah this issue is definitely still present in iOS 9. See comments on pull #5.

from awpercentdriveninteractivetransition.

rsanchezsaez avatar rsanchezsaez commented on July 22, 2024

I'm experiencing this problem as well. Pull Request #5 looks like a feasible solution.

Although note that, related to this, probably all this layer timing handling code should be done from the context itself instead of from the *PercentDrivenInteractiveTransition. See this documentation snippet from UIPercentDrivenInteractiveTransition's - updateInteractiveTransition: documentation:

This is a convenience method that calls through to the updateInteractiveTransition: method of the context object.

And the documentation on the same method on the UIViewControllerContextTransitioning protocol:

While tracking user events, gesture recognizers or your interactive animator objects should call this method regularly to update the progress toward completing the transition. If, during tracking, the interactions cross a threshold that you consider signifies the completion or cancellation of the transition, stop tracking events and call the finishInteractiveTransition or cancelInteractiveTransition method.

from awpercentdriveninteractivetransition.

MrAlek avatar MrAlek commented on July 22, 2024

As the comment I've written on #5 implies, I don't think it's a good enough solution.

I would much rather have the underlying problem fixed which is that UIView animations set their model properties on completion (see http://stackoverflow.com/questions/5040494/objective-c-ios-development-animations-autoreverse for instance). One could try to capture the incoming animation or introspect the CAPropertyAnimation objects that get created and reverse the model properties.

from awpercentdriveninteractivetransition.

MrAlek avatar MrAlek commented on July 22, 2024

And regarding the second comment, I agree with you in some sense. It should actually be the UIViewControllerTransitionCoordinator's job. Especially if you have other animations going alongside the transition.

The transition coordinator works with the animator objects to ensure that any extra animations are performed in the same animation group as the transition animations. Having the animations in the same group means that they execute at the same time and can all respond to timing changes provided by an interactive animator object. These timing adjustments happen automatically and do not require any extra code on your part.

The transition coordinator might also be involved in the screen flashing issue:

In addition to registering animations to perform during the transition, you can call the notifyWhenInteractionEndsUsingBlock: method to register a block to clean up animations associated with an interactive transition. Cleaning up is particularly important when the user cancels a transition interactively. When a cancellation occurs, you need to return to the original view hierarchy state as it existed before the transition.

I've spoken with Apple engineers about this and since the entire view controller transitioning mechanism was never meant to be used with custom container view controllers everything is a hack.

From the UIViewControllerContextTransitioning documentation:

Do not adopt this protocol in your own classes, nor should you directly create objects that adopt this protocol.

from awpercentdriveninteractivetransition.

foundry avatar foundry commented on July 22, 2024

Hello MrAlek. I too have hit up against this cancel-flash issue. Most reliably on a device (iphone 5s / ios9). Less reliably on the simulator, and not at all on a low-powered ipad mini v1. When it is evident, the affect is so noticable it makes this whole setup unusable.

The fix I have come up with seems to work, but it feels like a hack-on-top-of-a-hack. I have implemented it in the context of your container view controller interactive transition project.

1/ add a public property to your transitionContext object:

@property (nonatomic, strong) UIView* snapshotView;

2/ Create a snapshot of the fromView in the transitiionContext init method and add as a subView to the toView:

self.snapshotView = [fromViewController.view snapshotViewAfterScreenUpdates:NO];
[toViewController.view addSubview:self.snapshotView];
self.snapshotView.alpha = 0.0;

3/ In AWPercentDrivenIntercativeTranstion, set the snapshot alpha to 1.0 in - _transitionFinished if transitionWasCancelled is YES

   SEL selector = NSSelectorFromString(@"snapshotView");
    if ([_transitionContext respondsToSelector:selector]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
        [[_transitionContext performSelector:selector] setAlpha:1.0];
#pragma clang diagnostic pop

4/ Remove the snapshot in the transtionContext's -completeTranstion method:

- (void)completeTransition:(BOOL)didComplete {
    [self.snapshotView removeFromSuperview];
    if (self.completionBlock) {
        self.completionBlock (didComplete);
    }
}

Here is a link to my fork of your custom container transitions project with suggested fix. It would be better if we could remove that code from AWPercentDrivenInteractiveTransition and manage everything from inside the transitionContext, but that seems to be the precise point at which you need to show the shapshot. Any earlier, and you will see it during the interactive transition (the toView will mirror the fromView). Any later, and you are vulnerable to the flash.

This approach falls down completely when using a transitionCoordinator with animateAlongside - the alongside-animation is prone to the same flash issue - but it's the best I can come up with so far.

from awpercentdriveninteractivetransition.

kambala-decapitator avatar kambala-decapitator commented on July 22, 2024

My 5 cents:

while playing with https://github.com/MrAlek/custom-container-transitions to suit it to my needs (vertical transitions and different animations), what helped me to fix flickering was adding

[[self viewControllerForKey:UITransitionContextToViewControllerKey].view removeFromSuperview];

to the end of -cancelInteractiveTransition method of PrivateTransitionContext class.

from awpercentdriveninteractivetransition.

foundry avatar foundry commented on July 22, 2024

Removing the toViewController's view doesn't work in the general case - it just means you get a black-blink instead a (image-of-the-toView) blink. Thats why I cover the toView with a snapshot of the fromView. It still blinks, but the blink should be identical in appearance to the non-blinking state.

from awpercentdriveninteractivetransition.

angelmic avatar angelmic commented on July 22, 2024

Thanks, foundry.

Your patch works for me.

from awpercentdriveninteractivetransition.

drkibitz avatar drkibitz commented on July 22, 2024

I have this working, I'd be curious if it works for others or what you think, I guess it's whether or not this feels more or less like a worse hack than anything else 😉 :

- (void)_transitionFinished {
    [_displayLink invalidate];

    CALayer *layer = [_transitionContext containerView].layer;
    layer.speed = 1;

    if ([_transitionContext transitionWasCancelled]) {
        [CATransaction begin];
        [self _cancelBasicAnimationsInLayer:layer];
        [CATransaction commit];
    } else {
        CFTimeInterval pausedTime = [layer timeOffset];
        layer.timeOffset = 0.0;
        layer.beginTime = 0.0; // Need to reset to 0 to avoid flickering :S
        CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
        layer.beginTime = timeSincePause;
    }
}

- (void)_cancelBasicAnimationsInLayer:(CALayer *)layer {
    for (CALayer *sublayer in layer.sublayers) {
        [self _cancelBasicAnimationsInLayer:sublayer];
    }
    for (NSString *key in layer.animationKeys) {
        CAAnimation *animation = [layer animationForKey:key];
        if ([animation isKindOfClass:[CABasicAnimation class]]) {
            CABasicAnimation *basicAnim = (CABasicAnimation *)animation;
            [layer setValue:basicAnim.toValue forKeyPath:basicAnim.keyPath];
        }
    }
}

from awpercentdriveninteractivetransition.

drkibitz avatar drkibitz commented on July 22, 2024

I've tested that solution limitedly, but it seems to work great in 100% of all case I've had thus far. Makes this solution totally usable again, thanks!

from awpercentdriveninteractivetransition.

deberle avatar deberle commented on July 22, 2024

FWIW: I get the same flickering when using the standard UIPercentDrivenInteractiveTransition.

from awpercentdriveninteractivetransition.

Related Issues (5)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.