在UIPresentationController中动画呈现视图

时间:2014-11-10 19:29:26

标签: ios animation uiviewcontroller

在某些情况下,我建议阅读:

非常相关的问题:"From View Controller" disappears using UIViewControllerContextTransitioning 非常相关的答案:https://stackoverflow.com/a/25901154/751268


我正在尝试实现一个自定义视图控制器转换,动画新视图控制器覆盖屏幕的一半,同时将呈现视图控制器缩小到90%(在窗口中心,在呈现的视图控制器下面)。 / p>

首先,我的问题是viewFromKey:返回nil。为了解决这个问题,答案提到:

  

如果要为呈现视图控制器的视图设置动画,则应考虑使用UIModalPresentationFullscreen样式或继续使用UIModalPresentationCustom并使用UIPresentationController实现自己的shouldRemovePresentersView子类,并返回YES

我这样做了,viewFromKey:不再返回nil,但现在呈现的视图控制器完全消失了(考虑到我明确说它应该通过实现shouldRemovePresentersView)这是有道理的

我将呈现视图控制器的视图添加到容器视图中,但它仍然被删除。还有什么我应该做的才能让它发挥作用吗?

以下是一些相关代码:

UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey
UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];

BOOL show = self.isPresentation;
UIView *menuView = show ? toView : fromView;
UIView *backView = show ? fromView : toView;

UIView *containerView = [transitionContext containerView];

[containerView addSubview:backView];
[containerView addSubview:dimmedView];
[containerView addSubview:menuView];

// Adjust transforms, alpha and perform animations

我认为从YES返回shouldRemovePresentersView并手动将其添加到containerView,这应该可以解决问题,但无论如何都会删除backView ... < / p>

2 个答案:

答案 0 :(得分:5)

我正在添加另一个答案,因为我的回复太长而无法发表评论。

首先,viewForKey在iOS8中可用,因此,除非您仅针对iOS8(为什么?),否则不应使用它,或在检查UIViewControllerContextTransitioning响应该选择器后使用它并使用viewControllerForKey for iOS7。

话虽如此,在我看来,这是一个错误,我解释了自己:

如果查看UIPresentationController标题文件,您会看到它显示

// Indicate whether the view controller's view we are transitioning from will be removed from the window in the end of the
// presentation transition
// (Default: YES)
- (BOOL)shouldRemovePresentersView;

因此,当您看到默认值为YES时,因此只有在您特别想要拒绝时才应该覆盖。 但是,你是对的,如果没有将其明确设置为YES,viewForKey的{​​{1}}仍为零。

我认为你应该为此填写一份错误报告,现在使用UITransitionContextFromViewControllerKey,这可以使用(没有错),因为它不被弃用,适用于两个操作系统版本没问题。

这很可能是一个错误,因为当viewControllerForKey明确设置为<时,viewForKey应返回UITransitionContextFromViewControllerKey 的视图 strong> NO 而不是 YES

我的2美分

答案 1 :(得分:2)

如果您想要的是fromView仍然可见,为什么要将shouldRemovePresentersView设置为YES

我遇到了和你一样的问题,因为在我的自定义3d演示文稿中,转换完成后父视图控制器就被删除了。

解决方法是将modalPresentationStyle更改为UIModalPresentationOverCurrentContext 这将特别禁止系统在转换结束时删除所有者viewController。

使用这种方法时,我的3D过渡仍然受到动画问题的影响。

我最终使用UIModalPresentationCustom modalPresentationStyle解决了我几乎所有的问题,除了新的视图控制器(UINavigationController)在通话状态下不会向下移动吧会出现。

要解决此问题,我最后在转换完成之后将modalPresentationStyle更改回UIModalPresentationFullScreen

这是我的代码,它显示了带有自定义演示文稿的新viewController:

//show Login Screen
LoginViewController *viewController = [[LoginViewController alloc] initWithNibName:@"LoginViewController" bundle:nil];

UINavigationController *loginNavController = [[UINavigationController alloc] initWithRootViewController:viewController];
loginNavController.interactivePopGestureRecognizer.enabled = YES;
loginNavController.transitioningDelegate = self.customTransitionDelegate;
loginNavController.modalPresentationStyle = UIModalPresentationCustom;

[navigationController presentViewController:loginNavController animated:YES
                                 completion:^{
                                     //important, else status bar is not moving entire screen down....
                                     loginNavController.modalPresentationStyle = UIModalPresentationFullScreen;
                                 }
 ];

同样非常重要的是,在运行解雇动画时,您不得将旧视图添加到containerView

因此,如果动画是演示文稿,请将toView添加到containerView

    UIView* inView = [transitionContext containerView];

    UIViewController* toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    UIViewController* fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
.....
......

    [inView insertSubview:toViewController.view aboveSubview:fromViewController.view];

但是在解雇演示中,请不要将视图添加到containerView,因为它仍然显示(因为我们特别要求系统不要删除它),而只是在两个视图之间设置动画。