【问题标题】:"From View Controller" disappears using UIViewControllerContextTransitioning“来自视图控制器”使用 UIViewControllerContextTransitioning 消失
【发布时间】:2014-08-11 21:16:18
【问题描述】:

我遇到了一个问题,我在下面进行了描述。

我正在使用UIViewControllerContextTransitioning 进行自定义转换。

我有 2 个视图控制器,第一个视图控制器和第二个视图控制器。

现在我想用动画在第一个视图控制器上添加第二个视图控制器。我已经实现了,现在第二个视图控制器是透明的,所以我们可以在第二个视图控制器下面看到第一个视图控制器。

但是我看不到第一个视图控制器,我只能看到第二个视图控制器下方的黑屏。

-(void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext{
    self.transitionContext = transitionContext;
    if(self.isPresenting){
        [self executePresentationAnimation:transitionContext];
    }
    else{
       [self executeDismissalAnimation:transitionContext];
    }
  }

-(void)executePresentationAnimation:(id<UIViewControllerContextTransitioning>)transitionContext{
     UIView* inView = [transitionContext containerView];
     UIViewController* toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

     UIViewController* fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];

     CGRect offScreenFrame = inView.frame;
     offScreenFrame.origin.y = inView.frame.size.height;
     toViewController.view.frame = offScreenFrame;

    toViewController.view.backgroundColor = [UIColor clearColor];
    fromViewController.view.backgroundColor = [UIColor clearColor];
    inView.backgroundColor = [UIColor  clearColor];
    [inView insertSubview:toViewController.view aboveSubview:fromViewController.view];
     // [inView addSubview:toViewController.view];
    CFTimeInterval duration = self.presentationDuration;
    CFTimeInterval halfDuration = duration/2;

    CATransform3D t1 = [self firstTransform];
    CATransform3D t2 = [self secondTransformWithView:fromViewController.view];

    [UIView animateKeyframesWithDuration:halfDuration delay:0.0 options:UIViewKeyframeAnimationOptionCalculationModeLinear animations:^{

    [UIView addKeyframeWithRelativeStartTime:0.0f relativeDuration:0.5f animations:^{
        fromViewController.view.layer.transform = t1;
    }];

    [UIView addKeyframeWithRelativeStartTime:0.5f relativeDuration:0.5f animations:^{
        fromViewController.view.layer.transform = t2;
    }];
    } completion:^(BOOL finished) {
    }];


    [UIView animateWithDuration:duration delay:(halfDuration - (0.3*halfDuration)) usingSpringWithDamping:0.7f initialSpringVelocity:6.0f options:UIViewAnimationOptionCurveEaseIn animations:^{
        toViewController.view.frame = inView.frame;
    } completion:^(BOOL finished) {
        [self.transitionContext completeTransition:YES];
    }];
}

[self.transitionContext completeTransition:YES];调用时,突然第一个视图控制器消失,第二个视图控制器下方显示黑屏。

有人知道吗? 谢谢。

【问题讨论】:

    标签: ios iphone objective-c uiview transition


    【解决方案1】:

    我在关闭内容视图控制器时遇到了同样的问题。

    我的应用程序有这个父视图控制器,它以模态方式显示一个子视图控制器(呈现 vc)。然后当点击 childVC 中的子视图时,它会显示另一个 vc(我称之为内容视图控制器(呈现 vc))

    我的问题是,当关闭 contentVC(现在是呈现的 VC)时,它应该转到子 VC(现在是呈现的 VC),但是一旦我的自定义转换完成,childVC 突然消失,显示父 VC。

    我为解决这个问题所做的就是

    1. 将parentVC提供的childVC的.modalPresentationStyle从默认的.automatic更改为.fullscreen
    2. 然后将 contentVC 的 .modalPresentationStyle 也更改为 .fullscreen

    这解决了这个问题。但它不会将您的子 VC 显示为 parentVC 顶部的卡片样式表(使用 .overCurrentContext 或自动时),这是 iOS 13 中的新功能。

    想知道是否有任何解决方案可以在父母出示时为 childVC 保留卡片样式表。

    【讨论】:

      【解决方案2】:

      好的,伙计们,我想我解决了一个案例,即当您在 iOS 13 及更高版本中构建应用程序时,“工作中的动画师”停止正常工作。

      环境 Xcode 11.1、iOS 13.1

      问题

      我想做的很简单:我有一个集合视图,当一个单元格被点击时,它会转到一个详细视图。我不想使用无聊的默认样式“呈现模态”,而是想让它更有趣,所以我编写了一个用于视图控制器转换的动画师。

      我通过从我的收藏 VC 拖放到详细信息 VC 在 IB 中设置 segue。 segue 的样式是“Present modalally”,演示文稿设置为“Full Screen”。

      当它显示详细视图时,一切都按预期工作。但是,当我关闭详细视图并返回集合视图时,我只能看到动画详细视图,集合视图就消失了。我在这里和那里戳了一下,我有一些发现

      1.在从函数'animateTransition()'调用以下行之后,集合视图恢复并显示

      transitionContext.completeTransition(true)
      

      2.只要detail view没有完全覆盖collection view,collection view从detail view回退时不会消失

      解决方案

      说实话,我对动画过渡的工作原理知之甚少。所以我只能关注这个帖子和the other one,尝试每个答案。不幸的是,它们都不适合我。最后,我发现我唯一可以调整的是 IB 中 segue 的演示风格(我应该在一开始就这样做)。当我将演示文稿设置为“全屏显示”时,奇迹发生了,我的问题就解决了。细节视图可以全屏显示动画,当它关闭时,我可以看到集合视图作为背景和动画细节视图。

      然后在路上又发现了一个

      3.引用'toView'和'fromView',下面两种方法都可以

      间接方式:

      transitionContext.viewController(forKey: .to)?.view
      transitionContext.viewController(forKey: .from)?.view
      

      直接方式:

      transitionContext.view(forKey: .to)
      transitionContext.view(forKey: .from)
      

      但是当我将 segue 样式切换为“Over Full Screen”时,直接方式为“toView”和“fromView”返回“nil”,并且只有间接方式有效,another post 中也提到了这个问题,所以我认为值得在这里发布我的小发现。

      希望这对将来的某人有所帮助。

      【讨论】:

        【解决方案3】:

        遇到这个问题后,我很困惑,因为不久前我写了一些几乎相同的东西,效果很好。来这里寻找答案,以找到看起来很老套的修复程序,并且似乎不了解根本原因......实际上很容易修复。

        一些答案​​提到将modalPresentationStyle 更改为.overFullScreen。这是正确的,.overCurrentContext 也可以。这是意料之中的,也是 Apple 记录的行为。但是为什么这对每个人都不起作用?为什么所有的 hacky 代码,以及这些与其他东西的组合,以及你不应该做的疯狂的事情?

        事实证明,您需要在查看加载之前设置演示样式。不是之后。在 init 中执行,或者从前一个控制器执行,或者您想要的任何方式 - 只要它是在视图加载之前。

        【讨论】:

        • 我在视图加载之前(在视图控制器的 init 中)将演示样式设置为 .overCurrentContext ,但问题仍然存在
        【解决方案4】:

        我也被这个问题困住了。我正在寻找一个具有半透明背景的自定义过渡,我仍然可以看到我来自的视图控制器,但我只有一个黑色背景。我发现 Mark Aron 在这个帖子中的回答对我有帮助,但它是用 Objective C 编写的,所以这里是我为 iOS 9 和 iOS 10 测试过的那个答案的 Swift 3 版本:

        1. 创建 UIPresentationController 的子类。将 shouldRemovePresentersView 覆盖为 false,如下所示:

          class ModalPresentationController: UIPresentationController {
          
          override var shouldRemovePresentersView: Bool {
          return false
          }
          
          override func containerViewWillLayoutSubviews() {
          presentedView?.frame = frameOfPresentedViewInContainerView
          }
          }
          
        2. 在您实例化新视图控制器并设置其转换委托的地方,表明您希望它显示自定义模式表示样式,如下所示:

          let newVC = mainStoryboard.instantiateViewController(withIdentifier: "newVC") as! NewViewController 
          
          newVC.transitioningDelegate = self
          
          newVC.modalPresentationStyle = UIModalPresentationStyle.custom
          
          newVC.modalPresentationCapturesStatusBarAppearance = true //optional
          
          present(newVC, animated: true, completion: nil)
          
        3. 现在覆盖 UIViewControllerTransitioningDelegate 的 presentationController 方法并返回您的自定义 UIPresentationController。我有我的作为我当前课程的扩展:

          extension CurrentViewController: UIViewControllerTransitioningDelegate {
          
          //this is where you implement animationController(forPresented) and animationController(forDismissed) methods
          
          func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
          
          return ModalPresentationController(presentedViewController: presented, presenting: source)
          
          }
          }
          

        还有一点需要注意的是,您不应该尝试在您的 presentAnimator 类中引用您的 fromView。这将为 nil,您将在运行时收到错误。除此之外,如果您实现类似的东西,您将获得带有动画和半透明背景的自定义过渡。

        【讨论】:

        • 这个 iis 是在 Swift 3 中进行自定义模态演示的一个很好的例子!谢谢@gwinyai!在我找到一个示例显示presentationController(forPresented presented UIViewController,... 的新 swift 3 API 之前,我一直非常坚持,因为以前的 swift API 没有扰乱编译器,但没有被调用。
        【解决方案5】:

        我在 Lefteris 的相关主题中找到了这个非常有用的答案: https://stackoverflow.com/a/27165723/3709173

        总结一下:

        1. 将 modalPresentationStyle 设置为 .Custom
        2. 子类 UIPresentationController,覆盖 shouldRemovePresentersView(带 NO)
        3. 在您的 TransitionDelegate 类中覆盖presentationControllerForPresentedViewController 并返回您的自定义UIPresentationController

        在你的自定义过渡中+1,不要在解除动画发生时添加 toView。

        在这里演示:

        https://www.dropbox.com/s/7rpkyamv9k9j18v/CustomModalTransition.zip?dl=0 没有任何黑客!这就像魔术! :)

        【讨论】:

        • 这是真正的正确答案。没有像公认的魔术那样的魔术。谢谢,马克!
        • 不幸的是,这在 iOS 12.4、Xcode 10.3 中不起作用。转换完成后屏幕变黑(所有视图都已从层次结构中删除。但是,将“modalPresentationStyle”属性设置为“.fullscreen”确实有效。干杯。
        • 我在我的项目中尝试了 Mark 和 gwinyai 的 Swift 实现的 Obj-C 版本。不幸的是,它们都没有按预期工作。我使用的是 Xcode 11.1,构建目标是 iOS 13.0,我在设备和模拟器上都试过了。就我而言,我的基本设置是一个集合视图,当您点击一个单元格时,它会转到带有动画的详细视图。但是,如果我使用默认的过渡动画,它完全可以正常工作。当我从详细视图恢复时,呈现的 VC 不会消失。
        【解决方案6】:

        我发现如果您设置modalPresentationStyle = UIModalPresentationFullScreen,这个错误(以及更多!)就会消失。当然,您仍然可以获得自定义过渡动画。

        【讨论】:

          【解决方案7】:

          我发现viewForKey:UITransitionContextToViewKey 在 ios8 上返回 nil。所以如果它是 nil,我会从 'to' 视图控制器中获取视图。

          但是,这似乎导致在调用completeTransition:YES 时,“to”视图不会从容器移动到窗口。因此,如果viewForKey:UITransitionContextToViewKey 返回 nil,我将转到 toVC.view,并跟踪它返回 nil 的事实,并在完成后将其移动到容器的初始超级视图(恰好是窗口)。

          因此,此代码适用于 iOS7 和 iOS8,并且应该也适用于 iOS9,即使他们修复与否。

          - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext {
              // Get the 'from' and 'to' views/controllers.
              UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
              UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
              BOOL hasViewForKey = [transitionContext respondsToSelector:@selector(viewForKey:)]; // viewForKey is iOS8+.
              UIView *fromView = hasViewForKey ?
                  [transitionContext viewForKey:UITransitionContextFromViewKey] :
                  fromVC.view;
              UIView *toView = hasViewForKey ?
                  [transitionContext viewForKey:UITransitionContextToViewKey] :
                  toVC.view;
          
              // iOS8 has a bug where viewForKey:to is nil: http://stackoverflow.com/a/24589312/59198
              // The workaround is: A) get the 'toView' from 'toVC'; B) manually add the 'toView' to the container's
              // superview (eg the root window) after the completeTransition call.
              BOOL toViewNilBug = !toView;
              if (!toView) { // Workaround by getting it from the view.
                  toView = toVC.view;
              }
              UIView *container = [transitionContext containerView];
              UIView *containerSuper = container.superview; // Used for the iOS8 bug workaround.
          
              // Perform the transition.
              toView.frame = container.bounds;
              [container insertSubview:toView belowSubview:fromView];
              [UIView animateWithDuration:kDuration delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
                  fromView.frame = CGRectOffset(container.bounds, 0, CGRectGetHeight(container.bounds));
              } completion:^(BOOL finished) {
                  [transitionContext completeTransition:YES];
          
                  if (toViewNilBug) {
                      [containerSuper addSubview:toView];
                  }
              }];
          }
          

          【讨论】:

            【解决方案8】:

            我觉得应该更好地解释这背后的原因。

            视图消失是因为您将呈现视图控制器的视图从其原始位置(视图层次结构)中取出,将其放在动画师提供的 containerView 中,但在动画完成后永远不会将其返回。这样视图控制器的视图就被完全从窗口中删除,其父视图(containerView)。

            在 iOS 7 中,系统总是在转换自动完成动画后将视图控制器的视图返回到其原始位置,这些视图涉及演示(演示和演示)。 iOS 8 中的某些演示样式不再发生这种情况。

            规则非常简单:动画师应该只在呈现视图控制器的视图将在过渡结束完全隐藏(从视图层次结构中移除)时操作呈现视图控制器的视图。换句话说,这意味着在初始演示动画完成后,只有呈现的视图控制器的视图可见,而不是呈现视图控制器的视图。例如,如果您将呈现的视图控制器的视图的不透明度设置为 50% 并使用 UIModalPresentationFullScreen 您将无法在呈现的下方看到呈现视图控制器的视图,但如果您使用 UIModalPresentationOverFullscreen - 您将(UIPresentationController 的 shouldRemovePresentersView 方法负责指定) .

            为什么不允许动画师始终操纵呈现视图控制器的视图?首先,如果在整个演示生命周期中动画完成后呈现视图控制器的视图将保持可见,则根本不需要对其进行动画处理——它只是停留在原处。其次,如果该视图控制器的所有权转移给了展示控制器,那么展示控制器很可能在需要时不知道如何布局该视图控制器的视图,例如当方向改变时,但展示视图控制器的原始所有者知道.

            在 iOS 8 中引入了viewForKey: 方法来获取动画师操作的视图。首先,它有助于遵循上述规则,只要动画师不应该接触视图,就返回 nil。其次,它可能会返回一个 不同 视图供动画师制作动画。想象一下,您正在实现一个类似于表单的演示文稿。在这种情况下,您可能希望在呈现的视图控制器的视图周围添加一些阴影或装饰。动画师将为该装饰设置动画,并且呈现的视图控制器的视图将是该装饰的子视图。

            viewControllerForKey: 不会消失,如果需要直接访问视图控制器,它仍然可以使用,但动画师不应对其需要动画的视图做出任何假设。

            当您将其显式放置在动画制作者的容器视图中时,您可以做几件事来正确地解决呈现视图控制器的视图消失的问题:

            1. 如果不需要为呈现视图控制器的视图设置动画,请使用viewForKey: 让视图设置动画,而不是直接访问视图控制器的视图。 viewForKey: 可能返回 nil 甚至完全不同的视图。

            2. 1234563事实上,这种方法的实现是UIModalPresentationFullScreenUIModalPresentationCustom风格定义的内部表示控制器的主要区别,除了后者允许您使用自定义表示控制器。
            3. 在所有其他极少数情况下,您必须按照其他答案的建议将呈现视图控制器的视图返回到其原始位置。

            【讨论】:

            • 这太奇怪了,因为 this code 仅在 viewForKey: 返回 nil 时才依赖 viewControllerForKey:views,而我仍然必须重新添加它手动到窗口。您有没有这种解决方法的代码示例?
            • 好吧,如果viewForKey: 返回 nil,那么如果您在动画制作器中将其从窗口中移除,那么您肯定必须将呈现视图控制器的视图重新添加到窗口中。如果 viewForKey 返回实际视图控制器的视图,则移动该视图是安全的,因为 UIKit 会在演示生命周期结束后将其移回其原始位置。
            • 感谢您解释此问题背后的原因。你是绝对正确的。移动视图在视图层次结构中的位置而不替换它显然会使它消失(在 iOS 8 之后,我现在正在使用 iOS 10!)感谢您的澄清。
            • 感谢 egdmitry 的澄清。这又提出了另一个问题:您认为我应该如何实现类似 reveal 的演示文稿?当今非常常见的一种,其中呈现视图部分滑出以显示下方呈现的视图?在这种情况下,呈现视图和呈现视图都需要在屏幕上显示,并且呈现视图是动画的。
            【解决方案9】:

            使用新的 UIModalPresentationOverCurrentContext 为我修复了它。我在 iOS 7 上最初的过渡只是为了让模态下方的视图背景模糊。

            【讨论】:

            • 出于某种原因,这似乎不允许与下面的视图进行交互,而 UIModalPresentationCurrentContext 在 iOS 7 中所做的......有什么想法吗?
            • 嗯,在 iOS 10 上对我来说, .overCurrentContext 会导致此错误,但 .fullscreen 不会。我来到这里希望修复使用 .overCurrentContext 但到目前为止似乎没有任何东西可以在 iOS 10 中使用,除了可能是子类 UIPresentationController ...
            【解决方案10】:

            我发现这对 Obj-C 很有效:

                [transitionContext completeTransition:YES];
                if(![[UIApplication sharedApplication].keyWindow.subviews containsObject:toViewController.view]) {
                    [[UIApplication sharedApplication].keyWindow addSubview:toViewController.view];
                }
            

            似乎在 ios7 和 ios8 上都可以正常工作。

            【讨论】:

              【解决方案11】:

              在 iOS 8 中,您必须操作 viewForKey: 返回的视图,而不是 viewControllerForKey: 返回的视图控制器的 .view 属性。这在 beta 文档中并不是特别清楚,但是如果您查看 UIViewControllerTransitioning.h 的源代码,您会在 viewControllerForKey: 上方看到此评论:

              // Currently only two keys are defined by the
              // system - UITransitionContextToViewControllerKey, and
              // UITransitionContextFromViewControllerKey.
              // Animators should not directly manipulate a view controller's views and should
              // use viewForKey: to get views instead.
              - (UIViewController *)viewControllerForKey:(NSString *)key;
              

              所以不要调整toViewController.view的帧等,而是使用[transitionContext viewForKey:UITransitionContextToViewKey]的返回值。

              如果您的应用需要支持 iOS7 和/或 Xcode 5,那么您可以在 UIViewController 上使用简单的类别方法,如下所示:

              - (UIView *)viewForTransitionContext:(id<UIViewControllerContextTransitioning>)transitionContext
              {
              #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
                  if ([transitionContext respondsToSelector:@selector(viewForKey:)]) {
                      NSString *key = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey] == self ? UITransitionContextFromViewKey : UITransitionContextToViewKey;
                      return [transitionContext viewForKey:key];
                  } else {
                      return self.view;
                  }
              #else
                  return self.view;
              #endif
              }
              

              然后,照常获取您的toViewControllerfromViewController,但使用[toViewController viewForTransitionContext:transitionContext] 获取视图。

              编辑:似乎存在一个错误,当从viewForKey 返回时,呈现视图控制器的视图为零,这会阻止您进行模态转换来为呈现视图设置动画(例如滑开或翻转)水平的)。我在 rdar://17961976 (http://openradar.appspot.com/radar?id=5210815787433984) 提交了 iOS8 的错误。另请参阅http://github.com/bcherry/TransitionBug的示例项目

              编辑 2:感谢 Graveley 的建议,使用 UIModalPresentationFullScreen 解决了这个问题。也许这不是一个错误。 Apple 可能打算让 UIModalPresentationCustom 只修改传入模式的视图。如果要修改传出视图,需要保证新视图全屏呈现?在任何情况下,您都应该使用viewForKey 和 UIModalPresentationFullScreen。

              【讨论】:

              • viewForKey 错误快把我逼疯了!- 感谢提交。 FWIW 通过从 UITransitionContextToViewControllerKey 获取视图,我的转换工作正常,但我的转换只是将转换应用于整个视图。我不确定这是否应该被解释为manipulating VC 的观点......
              • 哇——太疯狂了。我没有在差异中看到这一点——可能是因为它只是一些小评论。当苹果推出这样的噱头时,真的很令人沮丧。手指交叉在你的雷达上。
              • 我在 GM 中也看到了 viewForKey 错误。其他人也一样吗?您是否找到了合理的解决方法?
              • 我认为根据- viewForKey 的评论 // viewForKey: 可能返回 nil 这表明动画师不应该操纵关联的视图控制器的视图。返回nil 不是错误。
              • @kenKuan 你可能是对的。使用 UIModalPresentationFullScreen 时,viewForKey 会返回 from view 和 to view。所以也许它是有意为 UIModalPresentationCustom 返回 nil 的。我正在更新我的错误报告,如果我收到 Apple 的回复,我会在此回复。
              【解决方案12】:

              这是 Ash 修复的 Objective C 版本。

              // my attempt at obj-c version of Ash's fix
              UIView *theToView = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey].view;
              [[[UIApplication sharedApplication] keyWindow] addSubview:theToView];
              [transitionContext completeTransition:YES]
              

              在重新添加视图后,我必须交换顺序并调用 [transitionContext completeTransition:] 方法,以便从另一个视图控制器的解除完成块中呈现一个新的视图控制器才能正常工作。

              我不知道这是否会为所有人解决问题,但它适用于我的应用程序。干杯!

              【讨论】:

                【解决方案13】:

                在 iOS 8 中,您需要创建一个 UIPresentationController 并在 UIViewControllerTransitioningDelegate 中实现以下方法。

                - (UIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented presentingViewController:(UIViewController *)presenting sourceViewController:(UIViewController *)source;
                

                在呈现视图控制器时,要求您的委托提供用于管理视图层次结构的自定义呈现控制器。

                返回值:

                用于管理模态演示的自定义演示控制器。

                讨论:

                当您使用 UIModalPresentation自定义展示样式,系统调用这个 方法并要求管理您的演示控制器 自定义样式。如果您实现此方法,请使用它来创建和 返回您要使用的自定义演示控制器对象 管理演示过程。

                如果你没有实现这个方法,或者如果你实现了这个 方法返回 nil,系统使用默认的演示控制器 目的。 默认的演示控制器不添加任何视图或 视图层次结构的内容。

                可用性 适用于 iOS 8.0 及更高版本。

                有关更多信息,请观看 WWDC 2014 视频:

                https://developer.apple.com/videos/wwdc/2014/?include=228

                还有一个来自 WWDC 的示例代码,名为“LookInside:Presentation Controllers Adaptivity and Custom Animator Objects”,您可以从 WWDC 2014 示例代码页下载。

                您可能需要稍微更改示例代码。 UIPresentationController init 方法改为:

                initWithPresentedViewController:presented presentingViewController:presenting
                

                在呈现之前,然后呈现。只需交换它们,它应该可以工作。

                【讨论】:

                • 很抱歉没有观看链接的视频,但我认为您不需要自定义 UIPresentationController,除非您想要在动画完成后进行非标准演示,例如圆形呈现视图。如果你只是想要一个不同的动画,基于我有限的知识,实现 UIViewControllerAnimatedTransitioning 应该就足够了。
                【解决方案14】:

                未将 modalPresentationStyle 设置为 UIModalPresentationCustom 为我解决了这个问题。

                换句话说,保留默认的 UIModalPresentationFullScreen 而不是指定 UIModalPresentationCustom 修复了视图消失的问题。请注意 UIViewControllerTransitioningDelegate 协议似乎仍然被遵循,即使将其保留为默认值。如果我没记错的话,曾几何时 UIModalPresentationCustom 是一项要求。

                到目前为止有效,仅对非交互式动画进行了尝试。

                【讨论】:

                • 哇。做到了!我在 iOS7 和 8 中不使用 modalPresentationStyle 进行了测试,并且在两者中都可以找到。谢谢!!
                • 谢谢!这与在viewControllerForKey: 上使用viewForKey: 而不是.view 相结合,为我解决了所有问题。
                • 这在不使用 viewForKey 的情况下为我解决了这个问题,但我想也应该使用它。
                • 虽然这似乎可以解决问题,但需要注意的是,视图控制器后面的屏幕一旦显示就会变黑。如果您的视图控制器不是全屏的,这一点很重要。
                • 成功了!谢谢?
                【解决方案15】:

                而不是 [inView insertSubview:toViewController.view aboveSubview:fromViewController.view]; 只需添加:[inView addSubview:toViewController.view];

                if (self.presenting) {
                
                    [transitionContext.containerView addSubview:toViewController.view];
                    // your code
                
                } else {
                    // your code
                }
                

                您可以在此处查看示例:link,它适用于 iOS 7 和 iOS 8

                【讨论】:

                • 这应该是执行 UIModalPresentationStyleCustom 类型动画的公认答案,因为不需要将 fromViewController 添加到 containerView。您只需要在呈现动画期间添加 toViewController。
                • 这很有帮助,其实
                【解决方案16】:

                我在这里遇到了同样的问题 - 看起来像是 iOS 8 中的一个错误。我有 filed a radar

                我使用Reveal 在屏幕变黑后检查视图层次结构。键 UIWindow 完全为空——根本没有视图层次结构!

                我玩了一下,看起来有一个简单的解决方法,对于简单的情况。您可以将toViewController 的视图重新添加为关键窗口的子视图:

                transitionContext.completeTransition(true)
                UIApplication.sharedApplication().keyWindow!.addSubview(toViewController.view)
                

                我已经检查过了,关键窗口的rootViewController 仍然设置正确,所以没关系。我不确定如果您从已经呈现的模态控制器中呈现控制器会发生什么,因此对于更复杂的情况,您必须进行试验。

                【讨论】:

                • 我也看到了这个问题。 iOS 8 引入了用于访问 fromView 和 toView 的新方法和键(注意:不是视图控制器)看起来好像这些引用在转换期间不会丢失。如果您刚刚从视图控制器中检索它们,您可以像往常一样将它们添加到容器视图中。
                • 在 viewDidLoad 中尝试将子视图添加到导航控制器的视图时,我看到了类似的 iOS 8 异常。将 navigationController 的视图重新添加到 keyWindow 似乎可以解决问题,非常感谢 Ash!
                • 我仍然在 GM 中看到了这一点(而且这个修复仍然有效)。其他人看到的一样吗?这只是 API 的变化吗?
                • 我发现如果您设置modalPresentationStyle = UIModalPresentationFullScreen,这个错误(以及更多!)就会消失。当然,您仍然可以获得自定义过渡动画。
                • 谢谢@AshFurrow。很好的解决方法,直到它被修复!
                【解决方案17】:

                添加一个视图控制器作为另一个视图控制器的子节点。

                [self addChildViewController:childViewController];                 
                

                检查并告诉我。

                【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2014-03-28
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多