如何像iOS 7的iPad App Store一样同时翻转和放大UIView?

4
iPad iOS 7应用商店在您点击应用图标时(从特色列表中,当图标较小时,而不是搜索结果),有一个非常酷的动画效果。下面是它的图片:
基本上,图标会翻转并同时扩大。
背景有渐变,内容视图较小。
到目前为止,我已经设置了自定义VC转换,并且已经使放大部分正常工作,但我无法使翻转同步。如何模仿应用商店的动画?
这是我目前的代码:
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
UIView *inView = [transitionContext containerView];
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *fromView = [fromVC view];
UIView *toView = [toVC view];
toView.frame = [transitionContext finalFrameForViewController:toVC];

// Take a snapshot of the new view being presented
UIGraphicsBeginImageContextWithOptions(toView.bounds.size, NO, 0);
CGContextRef ctx = UIGraphicsGetCurrentContext();
[fromView.layer renderInContext:ctx];
UIImage *snapshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

// Add the snapshot view and animate its appearance
UIImageView *intermediateView = [[UIImageView alloc] initWithImage:snapshot];
[inView addSubview:intermediateView];
[self calculateSourceRectInView:inView];
intermediateView.frame = self.sourceRect;

[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
    intermediateView.layer.transform = CATransform3DMakeRotation(-1.0 * -M_PI_2, 0.0, 1.0, 0.0);
    intermediateView.frame = toView.frame;
} completion:^(BOOL finished) {
    [intermediateView removeFromSuperview];

    if ([transitionContext transitionWasCancelled]) {
        [transitionContext completeTransition:NO];
    } else {
        [inView addSubview:toView];
        [fromView removeFromSuperview];
        [transitionContext completeTransition:YES];

        // Now this is a pushed view, we allow interactive
        // transitioning back to the parent view.
        self.interactiveTransition = [EBInteractiveZoomTransition new];
        [self.interactiveTransition wireToViewController:toVC];
    }
}];
}
3个回答

3
我在iPad App Store应用程序中拍摄了一段动画视频,它看起来不像是UIView转换。如果您慢慢播放,会发现有两个动画同时发生: 1) 图标旋转约90度,缩放和平移 2) 详细信息淡入,稍微旋转,缩放并平移到最终位置。因此详细信息并没有继续图标留下的位置。
我认为这就是使用视图动画时出现问题的原因。
为了实现更连续的视图翻转,请参阅以下代码。它基本上分几个步骤完成: 1) 将backView定位到frontView的位置 2) 使frontView旋转和缩放一半 3) 将backView变换设置为与frontView相同 4) 显示backView 5) 让backView旋转并缩放到最后的位置
翻转回去基本上是反向的。效果很好。
// flip and scale frontView to reveal backView to the center of the screen
// uses a containerView to mark the end of the animation
// parameterizing the destination is an exercise for the reader
- (void)flipFromFront:(UIView*)frontView toBack:(UIView*)backView
{
    float duration = 0.5;

    // distance from center of screen from frontView
    float dx = self.view.center.x - frontView.center.x;
    float dy = self.view.center.y - frontView.center.y;

    // this prevents any tearing
    backView.layer.zPosition = 200.0;

    // hide the backView and position where frontView is
    backView.hidden = NO;
    backView.alpha = 0.0;
    backView.frame = frontView.frame;

    // start the animation
    [UIView animateKeyframesWithDuration:duration
                                   delay:0.25
                                 options:UIViewKeyframeAnimationOptionCalculationModeCubic
                              animations:^{
                                  // part 1.  Rotate and scale frontView halfWay.
                                  [UIView addKeyframeWithRelativeStartTime:0.0
                                                          relativeDuration:0.5
                                                                animations:^{
                                                                    // get the transform for the blue layer
                                                                    CATransform3D xform = frontView.layer.transform;
                                                                    // translate half way
                                                                    xform = CATransform3DTranslate(xform, dx/2, dy/2, 0);
                                                                    // rotate half way
                                                                    xform = CATransform3DRotate(xform, M_PI_2, 0, 1, 0);
                                                                    // scale half way
                                                                    xform = CATransform3DScale(xform, 1.5, 1.5, 1);
                                                                    // apply the transform
                                                                    frontView.layer.transform = xform;
                                                                }];

                                  // part 2. set the backView transform to frontView so they are in the same
                                  // position.
                                  [UIView addKeyframeWithRelativeStartTime:0.5
                                                          relativeDuration:0.0
                                                                animations:^{
                                                                    backView.layer.transform = frontView.layer.transform;
                                                                    backView.alpha = 1.0;
                                                                }];

                                  // part 3.  rotate and scale backView into center of container
                                  [UIView addKeyframeWithRelativeStartTime:0.5
                                                          relativeDuration:0.5
                                                                animations:^{
                                                                    // undo previous transforms with animation
                                                                    backView.layer.transform = CATransform3DIdentity;
                                                                    // animate backView into new location
                                                                    backView.frame = self.containerView.frame;
                                                                }];
                              } completion:^(BOOL finished) {
                                  self.displayingFront = !self.displayingFront;
                              }];
}

// flip from back to front
- (void) flipFromBack:(UIView*)backView toFront:(UIView*)frontView
{
    float duration = 0.5;

    // get distance from center of screen to destination
    float dx = self.view.center.x - frontView.center.x;
    float dy = self.view.center.y - frontView.center.y;

    backView.layer.zPosition = 200.0;
    frontView.hidden = YES;

    // this is basically the reverse of the previous animation
    [UIView animateKeyframesWithDuration:duration
                                   delay:0
                                 options:UIViewKeyframeAnimationOptionCalculationModeCubic
                              animations:^{
                                  [UIView addKeyframeWithRelativeStartTime:0.0
                                                          relativeDuration:0.5
                                                                animations:^{
                                                                    CATransform3D xform = backView.layer.transform;
                                                                    xform = CATransform3DTranslate(xform, -dx/2, -dy/2, 0);
                                                                    xform = CATransform3DRotate(xform, M_PI_2, 0, 1, 0);
                                                                    xform = CATransform3DScale(xform, 0.75, 0.75, 1);
                                                                    backView.layer.transform = xform;
                                                                }];

                                  [UIView addKeyframeWithRelativeStartTime:0.5
                                                          relativeDuration:0.0
                                                                animations:^{
                                                                    backView.alpha = 0.0;
                                                                    frontView.hidden = NO;
                                                                }];

                                  [UIView addKeyframeWithRelativeStartTime:0.5
                                                          relativeDuration:0.5
                                                                animations:^{
                                                                    self.hiddenView.alpha = 0.0;
                                                                    frontView.layer.transform = CATransform3DIdentity;
                                                                }];
                              } completion:^(BOOL finished) {
                                  self.displayingFront = !self.displayingFront;
                              }];
}

3
尝试以下方法...
//set Intial Frame of view

[UIView transitionWithView: self.view
                  duration: 1.5f
                   options: UIViewAnimationOptionTransitionFlipFromRight
                animations: ^(void)
 {
 }
                completion: ^(BOOL isFinished)
 {
      // set the Final Frame of the View
 }];

1
尝试这段代码。
 [UIView transitionFromView:'yourOriginView'
                        toView:'yourDestination'
                      duration:0.65f
                       options:UIViewAnimationOptionTransitionFlipFromLeft/
                    completion:^(BOOL finished){
//    Do your presentation here
                    }];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接