如何通过拖动手指在两个视图之间执行翻转动画?

时间:2013-04-04 21:03:41

标签: ios animation view

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

我使用过这样的东西:

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出现。

你能帮助我吗?

3 个答案:

答案 0 :(得分:3)

您可以编写一个为您执行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];
    }
}

答案 1 :(得分:2)

你应该能够在UIPanGestureRecognizer(正在聆听手指拖动的手势识别器)的帮助下完成它,你将能够获得平移的长度,并从那里计算你的CATransform3D - 基于平移进度的翻译和缩放。

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

答案 2 :(得分:0)

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