【问题标题】:How to perform a flip animation between two views by dragging the finger?如何通过拖动手指在两个视图之间执行翻转动画?
【发布时间】:2013-04-06 06:46:20
【问题描述】:

我想在用户从屏幕右侧拖动手指时执行翻转动画。动画的状态应该受到拖动长度的影响,并且不应该自动工作。

我用过这样的东西:

if (transitionBegan) {

    flipTransition = CATransform3DIdentity;
    flipTransition.m34 = 1.0 / -500;
    flipTransition = CATransform3DRotate(flipTransition, degree * M_PI / 180.0f,0.0f, 1.0f, 0.0f);
    self.view.layer.transform = flipTransition;
}

但是现在不知道怎么实现视图之间的转换,让视图A消失,视图B出现。

你能帮帮我吗?

【问题讨论】:

  • 我假设您说的是随着用户手指移动(或暂停)而进行(或停止)的翻转。我认为您需要在这种情况下使用自定义容器,使用UIPanGestureRecognizer 导航。 This post 展示了如何使用推送式动画来做到这一点,但也可以进行调整以进行翻转注释。

标签: ios animation view


【解决方案1】:

您可以编写一个手势识别器来为您执行transform。例如,假设您能够左右翻转,您可以执行以下操作。但是这个想法是,如果您在翻转不到一半时转换当前视图,如果超过一半则转换下一个视图:

- (void)handlePan:(UIPanGestureRecognizer *)gesture
{
    static UIView *currentView;
    static UIView *previousView;
    static UIView *nextView;

    if (gesture.state == UIGestureRecognizerStateBegan)
    {
        // Set the three view variables here, based upon the logic of your app.
        // If there is no `previousView` or `nextView`, then set them to `nil`
        // as appropriate.

        // I happen to be choosing views for child view controllers for my 
        // custom container, but I'll spare you that in case you're not using
        // custom container controller.
    }

    // lets set the "percent" rotated as the percent across the screen the user's
    // finger has travelled

    CGPoint translation = [gesture translationInView:gesture.view.superview];
    CGFloat percent = translation.x / gesture.view.frame.size.width;
    CGFloat rotationPercent = percent;

    // let's use the var to keep track of which view will be rotated

    UIView *viewToTransform = nil; 

    if (percent < -0.5 && nextView)
    {
        // if user has moved finger more than half way across the screen to
        // the left, and there is a `nextView`, then we're showing the second
        // half of flip to the next screen

        currentView.hidden = YES;
        nextView.hidden = NO;
        previousView.hidden = YES;
        rotationPercent += 1.0;
        viewToTransform = nextView;
    }
    else if (percent > 0.5 && previousView)
    {
        // if user has moved finger more than half way across the screen to
        // the right, and there is a `previousView`, then we're showing the second
        // half of flip to the previous screen

        currentView.hidden = YES;
        nextView.hidden = YES;
        previousView.hidden = NO;
        rotationPercent -= 1.0;
        viewToTransform = previousView;
    }
    else if ((percent < 0 && nextView) || (percent > 0 && previousView))
    {
        // otherwise we're in the first half of the flip animation, so we're
        // showing the `currentView`

        currentView.hidden = NO;
        nextView.hidden = YES;
        previousView.hidden = YES;
        viewToTransform = currentView;
    }

    // do the flip `transform`

    CATransform3D transform = CATransform3DIdentity;
    transform.m34 = 1.0 / -800;
    viewToTransform.layer.transform = CATransform3DRotate(transform, M_PI * rotationPercent, 0.0, 1.0, 0.0);

    // if we're all done, let's animate the completion (or if we didn't move far enough,
    // the reversal) of the pan gesture

    if (gesture.state == UIGestureRecognizerStateEnded ||
        gesture.state == UIGestureRecognizerStateCancelled ||
        gesture.state == UIGestureRecognizerStateFailed)
    {
        // I'm personally using an index of my custom container child views, so I'm
        // just updating my index appropriately; your logic may obviously differ
        // here.

        if (percent < -0.5 && nextView)
            self.currentChildIndex++;
        else if (percent > 0.5 && previousView)
            self.currentChildIndex--;

        // and animate the completion of the flip animation

        [UIView animateWithDuration:0.25
                              delay:0.0
                            options:UIViewAnimationOptionCurveEaseInOut
                         animations:^{
                             previousView.transform = CGAffineTransformIdentity;
                             currentView.transform = CGAffineTransformIdentity;
                             nextView.transform = CGAffineTransformIdentity;
                         }
                         completion:NULL];
    }
}

【讨论】:

  • 从 iOS 7 开始,您可以使用基于块的 UIView 动画来使用交互式自定义过渡(参见 stackoverflow.com/a/10407713/1271826)。我会相应地更新这个答案。
【解决方案2】:

您应该能够在 UIPanGestureRecognizer(监听手指拖动的手势识别器)的帮助下完成此操作,您将能够获得 Pan 的长度,并从那里计算您的 @987654322跟随平移进度的基于 @ 的平移和缩放。

(内置动画在那儿没用,你必须在这里使用CoreAnimation,这很有趣,我可以告诉你;-))

【讨论】:

    【解决方案3】:

    使用UIView animateWithDuration: animations: completion: 方法将当前视图设置为动画直到过渡点,然后在完成块中移除当前视图,添加新视图并在新视图上开始另一个类似的动画。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多