iOS 7自定义展示和消失过渡效果

11

我正在制作自定义的进入和退出转换动画,并且遇到了一些问题。我想要的效果是重复 iOS 7 中打开/关闭某个应用程序时出现的深度动画。 我有第一个和第二个控制器。所有动画都在第一个控制器中(它支持UIViewControllerTransitioningDelegate和UIViewControllerAnimatedTransitioning)。所以,我只是在检查:如果正在展示 - 我会执行一个动画(先扩大第一个和第二个视图),如果正在退出 - 我会执行另一个动画(缩小第一个和第二个视图)。展示动画可以正常工作,但是退出动画存在问题。由于某种原因,当我缩小我的第二个控制器(它是UINavigationController)时,我看到黑色背景在它后面(这是错误的,因为我希望在它缩小时看到我的第一个控制器)。以下是来自第一个控制器的代码:

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
    UIView *transitionView = [transitionContext containerView];

    id toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    id fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];

    BOOL isPresenting;

    isPresenting = [toViewController isKindOfClass:[UINavigationController class]];

    UINavigationController *navigator = isPresenting ? toViewController : fromViewController;

    if (isPresenting) {
        [transitionView addSubview:navigator.view];
        navigator.view.transform = CGAffineTransformMakeScale(0.1, 0.1);
        navigator.view.alpha = 0;
    }

    navigator.view.center = self.startButton.center;

    void(^AnimationBlock)(void) = ^ {
        if (isPresenting) {
            navigator.view.transform = CGAffineTransformMakeScale(1, 1);
            self.view.transform = CGAffineTransformMakeScale(4, 4);
            navigator.view.alpha = 1;
            self.startButton.alpha = 0;
        } else {
            navigator.view.transform = CGAffineTransformMakeScale(0.1, 0.1);
            self.view.transform = CGAffineTransformMakeScale(1, 1);
            navigator.view.alpha = 0;
            self.startButton.alpha = 1;
        }
    };

    [UIView animateWithDuration:1
                          delay:0.0f
         usingSpringWithDamping:50.0
          initialSpringVelocity:4
                        options:UIViewAnimationOptionLayoutSubviews
                     animations:^{
                         AnimationBlock();
    } completion:^(BOOL finished) {
        [transitionContext completeTransition:YES];
        if (!isPresenting) {
            [navigator.view removeFromSuperview];
        }
    }];
}

- (void)completeTransitionInContext:(id<UIViewControllerContextTransitioning>)transitionContext{
    [transitionContext completeTransition:YES];
}


- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext{
    return 1;
}


- (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
    return self;
}

- (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
    return self;
}
请告诉我是否需要提供其他代码或屏幕截图。谢谢!

iOS 7 API仍然受NDA保护,直到公开发布(9月18日)。 - Vinzzz
我有一个非常类似的问题,而iOS7 API现在已经不再受NDA保护了... 你能否请解释一下如何解决它? 谢谢! - veducm
仍然不知道答案 :( - Nastya Gorban
3个回答

10

在呈现 toVC 后如果想要保留 fromVC 在窗口层级结构中,你需要在 toVC 上设置 modalPresentationStyle = UIModalPresentationCustom。

查看我对 WWDC Session 218: Custom Transitions Using View Controllers 的示例代码的实现。如果你点击“Options”,你会看到这种类型的转换效果。相关代码位于 SOLViewController.m prepareForSegue: 和 SOLOptionsTransitionAnimator.m。

https://github.com/soleares/SOLPresentingFun


6

当您呈现自定义VC时,应该使用: vc.modalPresentationStyle = UIModalPresentationCustom; 但是,如果您错误地键入了 vc.modalTransitionStyle = UIModalPresentationCustom; 您将在自定义VC后面得到一个黑色背景


1
谢谢您的发布。省了我好几个小时的时间。 - SmileBot

3
我认为,在实现 UIViewControllerTransitioningDelegate 时,使用两个不同的 AnimationController 类来控制 Present 和 Dismiss 动画是一个好主意。你可以在父级 ViewController 中实现 animationControllerForPresentedController 和 animationControllerForDismissedController 方法。
要创建 AnimationController,请继承 NSObject 并实现 UIViewControllerAnimatedTransitioning 协议。
希望这能帮到您。

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