容器视图在completeTransition上消失:

时间:2014-07-18 16:58:32

标签: ios objective-c uiview uiviewcontroller uiviewanimationtransition

我使用自定义视图控制器转换UIViewControllerAnimatedTransitioning来显示和关闭视图控制器。

呈现动画效果很好,但是当我运行解散动画时,一旦我调用completeTransition:containerView就会被删除。

我不确定发生了什么,这是转换代码:

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
    UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

    UIView *containerView = [transitionContext containerView];
    containerView.backgroundColor = [UIColor blackColor];

    if (self.reverse) {
        [containerView addSubview:toViewController.view];
        [containerView addSubview:fromViewController.view];
    } else {
        [containerView addSubview:fromViewController.view];
        [containerView addSubview:toViewController.view];
    }

    if (! self.reverse) { // Forward
        toViewController.view.frame = CGRectMake(-containerView.frame.size.width, 0, containerView.frame.size.width, containerView.frame.size.height);
    } else {
        fromViewController.view.frame = CGRectMake(0, 0, containerView.frame.size.width, containerView.frame.size.height);
    }

    [UIView animateWithDuration:[self transitionDuration:transitionContext] delay:0 usingSpringWithDamping:0.75f initialSpringVelocity:1.0f options:UIViewAnimationOptionCurveLinear animations:^{
        if (self.reverse) {
            fromViewController.view.frame = CGRectMake(-containerView.frame.size.width, 0, containerView.frame.size.width, containerView.frame.size.height);
            fromViewController.view.layer.opacity = 0.f;
            toViewController.view.layer.opacity = 1.f;
        } else {
            toViewController.view.frame = CGRectMake(0, 0, containerView.frame.size.width, containerView.frame.size.height);
            toViewController.view.layer.opacity = 1.f;
            fromViewController.view.layer.opacity = 0.3f;
        }
    } completion:^(BOOL finished) {
        [transitionContext completeTransition:finished];
    }];
}

- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
    if (self.reverse) {
        return 0.45;
    } else {
        return 0.35;
    }
}

如果toViewController设置为.reverse,如何防止YES消失?

更新:这就是我呈现视图控制器的方式:

SecondaryViewController *vc = [[SecondaryViewController alloc] init];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:vc];
navigationController.modalPresentationStyle = UIModalPresentationCustom;
navigationController.transitioningDelegate = self;
[self presentViewController:navigationController animated:YES completion:nil];

2 个答案:

答案 0 :(得分:51)

解雇时消失的容器视图是正确的行为。您的错误是将fromView添加到其中。

您错误地区分这是演示还是解雇以及您在每种情况下应该做什么。只需使用两个视图控制器fromViewControllertoViewController来区分它们;在解雇时,角色是相反的。解雇时,不要向内容视图添加任何内容;原始演示者仍然存在,并将通过删除容器视图显示。

因此,在演示时,只将toView添加到容器视图中。解雇时,不要向容器视图添加任何内容。就这么简单。

答案 1 :(得分:1)

我的解决方案是设置modalPresentationStyle = .custom。它可以在transitioningDelegate = self行之前或之后。

TLDR:

此讨论仅涉及呈现过渡,因为我对撤消过渡没有太多问题。

我的模式视图小于屏幕,并且当前视图应显示在背景中。但是,不,一旦调用transitionContext.completeTransition,我就会得到一个全黑的背景,而不是呈现视图。我有一个类似的模式视图,在代码的其他地方在后台显示了视图,并且完全可以正常工作。经过一些比较之后,我消除了所有其他可能性,并缩小到modalPresentationStyle = .custom的差异,该差异的默认值为.fullScreen。我猜.fullScreen假设所呈现的视图全屏显示,并决定删除该呈现者视图(fromView)。

modalPresentationStyle = .custom有关的一件有趣的事情:transitionContext.view(forKey: .from)返回nil,而transitionContext.viewController(forKey: .from)仍返回当前视图控制器。