iOS, как рассчитать продолжительность перехода при использовании UIDynamicAnimator для переходов контроллера представления?

Я модифицирую этот пример использования динамических аниматоров для переходов контроллера представления. Одна из вещей, которые я хочу сделать, - заставить его работать на iPad и изменить направление гравитационного перехода сверху вниз, справа налево. Мне интересно , есть ли способ рассчитать время перехода вида на основе размера вида, приложенной силы и направления силы тяжести? Другими словами, как долго, пока представление не достигнет правой границы и не отскочит от нее.

Я хочу вернуть эту правильную продолжительность из:

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

В примере, с которым я работаю, величина толчка установлена ​​на 100, что работает для экранов iPhone, но "слишком медленно" для экрана iPad. Из того, что я понимаю, сила применяется к размеру экрана, где экран iPad требует более сильного толчка, чтобы сдвинуть его вовремя.

Поэтому я изменил код следующим образом:

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

Что работает, но сейчас я не знаю, сколько времени займет новый переход. Значение по умолчанию составляет 1,5 секунды, что работает, но если я установлю его на 0,7 с, представление застревает на полпути при переходе.

- (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;
}

1 ответ

UIDynamicAnimator имеет этот метод делегата: dynamicAnimatorDidPause: когда представления достигают статического состояния, он будет вызван. Поэтому поместите ссылку на transitionContext (например, слабое свойство), установите делегат аниматора в self и вызовите completeTransition:.

-(void)dynamicAnimatorDidPause:(UIDynamicAnimator *)animator
{
    [self.transitionContext completeTransition:finished];
}
Другие вопросы по тегам