iOS 使用 UIDynamicAnimator 进行视图控制器转换时如何计算转换持续时间?

Posted

技术标签:

【中文标题】iOS 使用 UIDynamicAnimator 进行视图控制器转换时如何计算转换持续时间?【英文标题】:iOS how to calculate transition duration when using UIDynamicAnimator for view controller transitions? 【发布时间】:2014-09-09 16:03:43 【问题描述】:

我正在修改this example of using dynamic animators for view controller transitions。我想做的一件事是让它在 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;

【问题讨论】:

我相信至少现在这是不可能的。除非苹果提供不需要transitionDuration的过渡协议@ 【参考方案1】:

UIDynamicAnimator 有这个委托方法:dynamicAnimatorDidPause: 当视图达到静态时,它将被调用。所以放一个对 transitionContext 的引用(就像一个弱属性),将动画代理设置为 self 并调用 completeTransition:。

-(void)dynamicAnimatorDidPause:(UIDynamicAnimator *)animator

    [self.transitionContext completeTransition:finished];

【讨论】:

以上是关于iOS 使用 UIDynamicAnimator 进行视图控制器转换时如何计算转换持续时间?的主要内容,如果未能解决你的问题,请参考以下文章

iOS:UIDynamicAnimator updateItemUsingCurrentState 不适用于旋转

UIDynamicAnimator + 自定义 UICollectionViewLayout 导致永久圆周运动

UIDynamicAnimator items(in:) 在 iOS 11 中崩溃

为啥我的 UIDynamicAnimator 类继承不能使用 addChildBehavior

减慢 UIDynamicAnimator 的动画

使用自动布局时使用 UIDynamicAnimator 制作动画