IOS how to calculate transition duration when using UIDynamicAnimator for view controller transitions?

I am modifying this example of using dynamic animators for view controller transitions . One of the things I want to do is make it work on iPad and change the direction of gravity from top to bottom to right to left. I'm wondering if I have a way to calculate the transition time to a view based on the size of the view, the force applied, and the direction of gravity? In other words, how long until the image falls to the right of the border and stops bouncing off it.

I want to return this correct duration from:

- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext

      

The example I'm working with has a push value set to 100, which works on iPhones, but is "too slow" for an iPad. From what I understand, force is applied to screen size, where the iPad screen requires more pressure to move it through time.

So, I changed the code like this:

pushBehavior.pushDirection = CGVectorMake(1,0);
pushBehavior.magnitude = 700.0;
UIGravityBehavior *gravityBehavior = [[UIGravityBehavior alloc] initWithItems:@[toViewController.view]];
gravityBehavior.gravityDirection = CGVectorMake(-1.0, 0);

      

Which works, but now I don't know how long the new transition will take. The default is 1.5 seconds, which works, but if I set it to 0.7s, the view gets stuck halfway through the transition.

- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
    return 1.5f;
}


- (UIDynamicAnimator*)animateForTransitionContext:(id<UIViewControllerContextTransitioning>)transitionContext {
    // Get the view controllers for the transition
    UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];


    // Prepare the view of the toViewController
    toViewController.view.frame = CGRectOffset(fromViewController.view.frame, 1.0f*fromViewController.view.frame.size.width,0);


    // Add the view of the toViewController to the containerView
    [[transitionContext containerView] addSubview:toViewController.view];

    // Create animator
    UIDynamicAnimator *animator = [[UIDynamicAnimator alloc] initWithReferenceView:[transitionContext containerView]];

    // Add behaviors
    UIGravityBehavior *gravityBehavior = [[UIGravityBehavior alloc] initWithItems:@[toViewController.view]];
    gravityBehavior.gravityDirection = CGVectorMake(-1.0, 0);

    UICollisionBehavior *collisionBehavior = [[UICollisionBehavior alloc] initWithItems:@[toViewController.view]];


    [collisionBehavior addBoundaryWithIdentifier:@"LeftBoundary" fromPoint:CGPointMake(0,0) toPoint:CGPointMake(0.0f, fromViewController.view.frame.size.height+1)];


    UIDynamicItemBehavior *propertiesBehavior = [[UIDynamicItemBehavior alloc] initWithItems:@[toViewController.view]];
    propertiesBehavior.elasticity = 0.2;

    UIPushBehavior *pushBehavior = [[UIPushBehavior alloc] initWithItems:@[toViewController.view] mode:UIPushBehaviorModeInstantaneous];
//    pushBehavior.angle = 0;
    pushBehavior.pushDirection = CGVectorMake(-1, 0);
    pushBehavior.magnitude = 700.0;

    [animator addBehavior:pushBehavior];
    [animator addBehavior:propertiesBehavior];
    [animator addBehavior:collisionBehavior];
    [animator addBehavior:gravityBehavior];

    return animator;
}

      

+3


source to share


1 answer


UIDynamicAnimator has this delegation method: dynamicAnimatorDidPause: When the views reach a static state, it will be called. So put a reference to the transitionContext (like a weak property), set the animator delegate to yourself, and call completeTransition :.



-(void)dynamicAnimatorDidPause:(UIDynamicAnimator *)animator
{
    [self.transitionContext completeTransition:finished];
}

      

0


source







All Articles