0

我尝试制作 3D 动画

- (void)transitionFromViewController:(UIViewController *)fromViewController toViewController:(UIViewController *)toViewController duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion;

我在 UINavigationController "PushViewController" 3D Animation Happen Throw 中编写 3D 动画

- (void) pushViewController:(UIViewController *)viewController animated:(BOOL)animated transitionDirecton:(CubeNavigationAnimationDirection)direction{

    UIViewController *current = self.visibleViewController;

    viewController.view.frame = current.view.frame;

    CGFloat halfWidth = current.view.bounds.size.width / 2.0;
    CGFloat duration = 0.7;
    CGFloat perspective = -1.0/1000.0;

    UIView *superView = current.view.superview;
    CATransformLayer *transformLayer = [[CATransformLayer alloc] init];
    transformLayer.frame = current.view.layer.bounds;

    [current.view removeFromSuperview];
    [transformLayer addSublayer:current.view.layer];
    [transformLayer addSublayer:viewController.view.layer];
    [superView.layer addSublayer:transformLayer];

    // let's be safe about setting stuff on view's we don't control
    UIColor *originalBackgroundColor = superView.backgroundColor;
    superView.backgroundColor = [UIColor blackColor];

    [CATransaction begin];
    [CATransaction setDisableActions:YES];
    CATransform3D transform = CATransform3DIdentity;



    if (animated) {
        if (direction == CubeNavigationAnimationOutside) {
            transform = CATransform3DTranslate(transform, 0, 0, -halfWidth);
            transform = CATransform3DRotate(transform,-M_PI_2, 0, 1, 0);
            transform = CATransform3DTranslate(transform, 0, 0, halfWidth);
        }
        else{
            transform = CATransform3DTranslate(transform, 0, 0, halfWidth);
            transform = CATransform3DRotate(transform, M_PI_2, 0, 1, 0);
            transform = CATransform3DTranslate(transform, 0, 0, -halfWidth);
        }
    }

    viewController.view.layer.transform = transform;
    [CATransaction commit];

    [CATransaction begin];
    [CATransaction setCompletionBlock:^(void) {
        [viewController.view.layer removeFromSuperlayer];
        viewController.view.layer.transform = CATransform3DIdentity;
        [current.view.layer removeFromSuperlayer];
        superView.backgroundColor = originalBackgroundColor;
        [superView addSubview:current.view];
        [transformLayer removeFromSuperlayer];
        [self pushViewController:viewController animated:NO];
        self.view.userInteractionEnabled = YES;
    }];

    CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];

    transform = CATransform3DIdentity;
    transform.m34 = perspective;
    transformAnimation.fromValue = [NSValue valueWithCATransform3D:transform];

    transform = CATransform3DIdentity;
    transform.m34 = perspective;

    if (animated) {
        if (direction == CubeNavigationAnimationOutside) {
            transform = CATransform3DTranslate(transform, 0, 0, -halfWidth);
            transform = CATransform3DRotate(transform, M_PI_2, 0, 1, 0);
            transform = CATransform3DTranslate(transform, 0, 0, halfWidth);
        }
        else{
            transform = CATransform3DTranslate(transform, 0, 0, halfWidth);
            transform = CATransform3DRotate(transform,-M_PI_2, 0, 1, 0);
            transform = CATransform3DTranslate(transform, 0, 0, -halfWidth);
        }
    }



    transformAnimation.toValue = [NSValue valueWithCATransform3D:transform];

    transformAnimation.duration = duration;

    [transformLayer addAnimation:transformAnimation forKey:@"rotate"];
    transformLayer.transform = transform;

    [CATransaction commit];

}

当我尝试在 transitionFromViewController 中重用此代码时

[self transitionFromViewController:fromViewController
                      toViewController:toViewController
                              duration:3.0
                               options:UIViewAnimationOptionTransitionNone
                            animations:^{
                                toViewController.view.frame = fromViewController.view.frame;

                                CGFloat halfWidth = fromViewController.view.bounds.size.width / 2.0;
                                CGFloat duration = 0.7;
                                CGFloat perspective = -1.0/1000.0;

                                UIView *superView = fromViewController.view.superview;
                                CATransformLayer *transformLayer = [[CATransformLayer alloc] init];
                                transformLayer.frame = fromViewController.view.layer.bounds;

                                [fromViewController.view removeFromSuperview];
                                [transformLayer addSublayer:fromViewController.view.layer];
                                [transformLayer addSublayer:toViewController.view.layer];
                                [superView.layer addSublayer:transformLayer];

                                // let's be safe about setting stuff on view's we don't control
                                UIColor *originalBackgroundColor = superView.backgroundColor;
                                superView.backgroundColor = [UIColor blackColor];

                                [CATransaction begin];
                                [CATransaction setDisableActions:YES];
                                CATransform3D transform = CATransform3DIdentity;




                                    if (direction == CubeTransitionDirectionFromRight) {
                                        transform = CATransform3DTranslate(transform, 0, 0, -halfWidth);
                                        transform = CATransform3DRotate(transform,-M_PI_2, 0, 1, 0);
                                        transform = CATransform3DTranslate(transform, 0, 0, halfWidth);
                                    }
                                    else{
                                        transform = CATransform3DTranslate(transform, 0, 0, halfWidth);
                                        transform = CATransform3DRotate(transform, M_PI_2, 0, 1, 0);
                                        transform = CATransform3DTranslate(transform, 0, 0, -halfWidth);
                                    }



                                toViewController.view.layer.transform = transform;
                                [CATransaction commit];

                                [CATransaction begin];
                                [CATransaction setCompletionBlock:^(void) {
                                    [toViewController.view.layer removeFromSuperlayer];
                                    toViewController.view.layer.transform = CATransform3DIdentity;
                                    [fromViewController.view.layer removeFromSuperlayer];
                                    superView.backgroundColor = originalBackgroundColor;
                                    [superView addSubview:fromViewController.view];
                                    [transformLayer removeFromSuperlayer];
                                    toViewController.view.userInteractionEnabled = YES;
                                }];

                                CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];

                                transform = CATransform3DIdentity;
                                transform.m34 = perspective;
                                transformAnimation.fromValue = [NSValue valueWithCATransform3D:transform];

                                transform = CATransform3DIdentity;
                                transform.m34 = perspective;


                                    if (direction == CubeTransitionDirectionFromRight) {
                                        transform = CATransform3DTranslate(transform, 0, 0, -halfWidth);
                                        transform = CATransform3DRotate(transform, M_PI_2, 0, 1, 0);
                                        transform = CATransform3DTranslate(transform, 0, 0, halfWidth);
                                    }
                                    else{
                                        transform = CATransform3DTranslate(transform, 0, 0, halfWidth);
                                        transform = CATransform3DRotate(transform,-M_PI_2, 0, 1, 0);
                                        transform = CATransform3DTranslate(transform, 0, 0, -halfWidth);
                                    }


                                transformAnimation.toValue = [NSValue valueWithCATransform3D:transform];

                                transformAnimation.duration = duration;

                                [transformLayer addAnimation:transformAnimation forKey:@"rotate"];
                                transformLayer.transform = transform;

                                [CATransaction commit];

                            }
                            completion:^(BOOL finished) {
                                [toViewController didMoveToParentViewController:self];
                                [fromViewController removeFromParentViewController];
                            }];

和 3D 动画发生但 toViewController 在动画后消失.. 任何人都可以帮助我吗?

4

1 回答 1

0

您在 transitionFromViewController: 方法调用之前缺少 2 行:

[fromViewController willMoveToParentViewController:nil];
[self addChildViewController:toViewController];

对于添加视图控制器,基本上你需要在动画之前平衡didMoveToParentViewController的调用和addChildViewController(它会自动调用willMoveToParentViewController)。

对于视图控制器的删除,您需要在动画之前平衡removeFromParentViewController的调用(这将自动调用didMoveToParentViewController)和willMoveToParentViewController

查看 UIViewController 类参考:实现容器视图控制器

于 2013-06-10T15:09:59.870 回答