【问题标题】:Animating the presenting view in a UIPresentationController在 UIPresentationController 中动画呈现视图
【发布时间】:2015-01-07 05:01:50
【问题描述】:

对于某些情况,我建议阅读以下内容:

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


我正在尝试实现自定义视图控制器转换,以动画方式使新视图控制器覆盖一半屏幕,同时将呈现视图控制器缩小到 90%(在窗口居中,在呈现视图控制器下方)。

首先,我的问题是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

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

【问题讨论】:

  • 我不确定它是否会帮助你,但前几天我刚刚观看了一个 WWDC 会议,涵盖了这种类型的演示文稿,并附有演示。 “查看演示控制器”它是 WWDC 应用程序上提供的“会话 228”。
  • 我以前看过,虽然我不记得具体听说过。不过我还是会再看一遍的。
  • 您找到解决方案了吗?我正在为此苦苦挣扎,如果它是一个错误,我很惊讶它尚未修复。

标签: ios animation uiviewcontroller


【解决方案1】:

我正在添加另一个答案,因为我的回复太长,无法放入评论中。

首先viewForKey在iOS8中可用,所以除非你只针对iOS8(为什么?)你不应该使用它,或者在检查UIViewControllerContextTransitioning响应该选择器并使用@之后使用它iOS7 为 987654323@。

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

如果你查看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,UITransitionContextFromViewControllerKeyviewForKey 仍然为零。

我认为您应该为此填写一份错误报告,现在使用 viewControllerForKey 可以很好地使用(这没什么问题),因为它没有被弃用,并且在两个操作系统版本中都可以正常工作。

这很可能是一个错误的原因是viewForKey 应该返回UITransitionContextFromViewControllerKey 的视图shouldRemovePresentersView 明确设置为NO 而不是YES

我的 2 美分

【讨论】:

  • 这不是最清晰的 API,如果您不确定某些行为是由于 iOS 8 中的错误还是您自己的代码中的错误,则尤其困难,但这确实是有道理的。谢谢!
【解决方案2】:

如果您希望 fromView 保持可见,为什么要将 shouldRemovePresentersView 设置为 YES

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

解决方案是将modalPresentationStyle 更改为UIModalPresentationOverCurrentContext 这将明确禁止系统在过渡结束时移除所有者 viewController。

使用这种方法时,我的 3D 过渡仍然存在动画问题。

我最终使用了UIModalPresentationCustommodalPresentationStyle,它几乎解决了我所有的问题,除了新的视图控制器(它是一个 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,因为它仍在显示(因为我们特别要求系统不要删除它),而只是在两个视图之间设置动画。

【讨论】:

  • shouldRemovePresentersView返回YES的原因是这将导致viewForKey:不返回nil。我在这里寻找 iOS 8 解决方案,文档明确指出,如果我们需要访问其中一个视图控制器的视图,我们应该使用 viewForKey:,而不是 viewForViewController:(这就是你正在做的事情)。在 iOS 7 中这很好,但我正在寻找如何在 iOS 8 中完成。
  • 嗯,我正在 iOS8 上测试它,它工作正常。 the documentation 似乎也没有表明我们不应该直接使用 ViewController。
  • UIViewControllerTransitioning.h:“动画师不应直接操纵视图控制器的视图,而应使用 viewForKey: 来获取视图。”我们仍然可以使用viewControllerForKey:,但是当我们只想要它的视图时就不行了。
  • 我还尝试更改完成块中的 modalpresentationStyle,它适用于 iOS 9,但不适用于 iOS 8.. 有什么想法吗?
猜你喜欢
  • 1970-01-01
  • 2021-01-03
  • 2022-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多