使用UIViewControllerContextTransitioning,“来自View Controller”消失


105

我遇到一个问题,下面已经描述了。

我正在使用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];调用时,突然的第一视图控制器消失,下面第二视图控制器黑色屏幕。

有人有主意吗?谢谢。

Answers:


98

我在这里有同样的问题-看起来像iOS的8中的错误,我提出了雷达

屏幕变黑后,我使用了Reveal检查视图层次。关键UIWindow是完全空的-根本没有视图层次!

显示

我玩了一些,对于简单的情况,似乎有一个简单的解决方法。您只需将toViewController的视图重新添加为键窗口的子视图即可:

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

我已经检查过,并且关键窗口的rootViewController设置仍然正确,所以很好。我不确定如果从已经显示的模态控制器中显示控制器会发生什么,因此对于更复杂的情况,您将不得不进行试验。


2
我也看到了这个问题。iOS 8引入了一种新的方法和用于访问fromView和toView的键(注意:不是视图控制器)在过渡期间,这些引用似乎没有丢失。如果您只是从视图控制器中检索到它们,则可以像往常一样将它们添加到容器视图中。
塔皮

1
尝试在viewDidLoad中将子视图添加到导航控制器的视图时,我看到类似的iOS 8怪异现象。重新将navigationController的视图添加到keyWindow似乎可以解决问题,非常感谢Ash!
taber 2014年

1
我仍然在GM中看到此消息(并且此修复程序仍然有效)。其他人也一样吗?这仅仅是对API的更改吗?
rjkaplan 2014年

21
我发现,如果设置,此bug(以及更多!)将消失modalPresentationStyle = UIModalPresentationFullScreen。当然,您仍然可以获得自定义过渡动画。
克里斯(Chris)

1
谢谢@AshFurrow。好的方法,直到它被修复!
kandelvijaya

78

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

该视图消失是因为您从当前视图控制器的原始位置(视图层次结构)中取出了该视图,将其放入了动画设计人员提供的containerView中,但在动画完成后再也不会将其返回。因此,该视图控制器的视图及其超级视图(containerView)将从窗口中完全删除。

在iOS 7中,系统会始终在过渡自动完成动画设置后,将演示文稿(演示文稿和演示文稿)中涉及的视图控制器的视图返回到其原始位置。对于iOS 8中的某些演示样式,这不再发生。

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

为什么不让动画师始终操纵呈现视图控制器的视图?首先,如果在整个演示生命周期中动画结束后,呈现视图控制器的视图将保持可见状态,则根本不需要对其进行动画处理-它将停留在原处。其次,如果该视图控制器的所有权已转移到演示控制器,则演示控制器很可能不知道如何在需要时(例如,方向发生变化时)布局该视图控制器的视图,但是演示视图控制器的原始所有者会。

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

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

当您将其显式放置在动画师的容器视图中时,可以采取几种措施来正确地解决呈现视图控制器视图消失的问题:

  1. 如果不需要对呈现的视图控制器的视图viewForKey:进行动画处理,请使用使视图进行动画处理,而不是直接伸出手来查看控制器的视图。viewForKey:可能会返回nil甚至完全不同的视图。

  2. 如果你想动画呈现视图控制器的观点,你应该考虑使用UIModalPresentationFullScreen样式或继续使用UIModalPresentationCustom,并实现自己的UIPresentationController的子类shouldRemovePresentersView返回YES。实际上,此方法的实现是UIModalPresentationFullScreen和定义的内部表示控制器之间的主要区别,UIModalPresentationCustom除了后者允许您使用自定义表示控制器。

  3. 在所有其他罕见情况下,您将不得不将呈现视图控制器的视图返回到其原始位置,如建议的其他答案一样。


2
这是超级奇怪,因为这个代码依赖viewControllerForKey:view唯一时viewForKey:返回nil,我仍然不得不手动将其重新添加到窗口。如果没有这种解决方法,您是否有代码示例?
Ash Furrow,2014年

好吧,如果viewForKey:返回nil,那么如果您将其从动画制作器中删除,则必须确保将呈现视图控制器的视图重新添加到窗口中。如果viewForKey返回实际视图控制器的视图,则可以安全地移动该视图,因为在演示生命周期结束后,UIKit会将其移回其原始位置。
egdmitry

感谢您解释此问题背后的原因。你是绝对正确的。在不替换视图的情况下移动视图在视图层次结构中的位置显然会使其消失(在iOS 8之后,我现在正在使用iOS 10!)感谢您的澄清。
克莱·埃利斯

1
感谢egdmitry的澄清。由此引发的另一个问题是:你是怎么想我应该实现一个显示像演示?当今非常普遍的一种视图,其中呈现视图部分滑出以显示其下方的呈现视图?在这种情况下,呈现视图和呈现视图都需要在屏幕上显示,并且呈现视图是一个动画视图。
安德里亚(Andrea)

70

在iOS 8中,您必须操纵所返回的视图,viewForKey:而不是所.view返回的视图控制器的属性viewControllerForKey:。从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]

编辑:似乎存在一个错误,当从中返回时,当前视图控制器的视图为nil viewForKey,这将阻止您进行使当前视图具有动画效果的模式转换(例如,滑动或水平翻转)。我在rdar:// 17961976(http://openradar.appspot.com/radar?id=5210815787433984)上提交了iOS8的错误。另请参见位于http://github.com/bcherry/TransitionBug的示例项目

编辑2:感谢graveley的建议,使用UIModalPresentationFullScreen可以解决此问题。也许这不是一个错误。苹果可能打算让UIModalPresentationCustom仅修改传入模式的视图。如果要修改传出视图,是否需要保证新视图的全屏显示?无论如何,您应该使用viewForKey和UIModalPresentationFullScreen。


2
viewForKey错误使我发疯!-感谢归档。FWIW通过从UITransitionContextToViewControllerKey获取视图,我的过渡效果很好,但是我的过渡仅将变换应用于整个视图。我不确定是否应该将其解释为manipulatingVC的观点……
MathewS 2014年

1
哇-真是疯了。我没有在差异中看到它-可能是因为这只是一些小评论。当苹果这样的绝技时,真让人沮丧。手指交叉在雷达上。
Ash Furrow 2014年

我也看到了viewForKey通用汽车中的错误。还有其他人吗?您是否找到了合理的解决方法?
rjkaplan 2014年

2
我认为,根据- viewForKey// // viewForKey的注释,可能返回nil,这将指示动画制作者不应操纵关联的视图控制器的视图。返回nil不是错误。
肯宽

4
@kenKuan你可能是对的。使用UIModalPresentationFullScreen时, viewForKey确实返回from视图和to视图。因此,可能有意为UIModalPresentationCustom返回nil。我正在更新我的错误报告,如果我从Apple收到有关该错误的报告,将会在此发布。
樱桃

24

未设置modalPresentationStyle为UIModalPresentationCustom为我解决了此问题。

换句话说,保留默认的UIModalPresentationFullScreen而不是指定UIModalPresentationCustom可以解决消失的视图问题。请注意,即使将其保留为默认值,仍然似乎遵循UIViewControllerTransitioningDelegate协议。如果我没记错的话,从前UIModalPresentationCustom是一个要求。

迄今为止的作品,仅针对非交互式动画尝试过此方法。


1
哇。做到了!我没有在iOS7和8中使用modalPresentationStyle进行测试,并且在两者中都能找到它。谢谢!!
Ah Ryun Moon 2014年

1
谢谢!这与使用viewForKey:而不是.viewviewControllerForKey:修复上对我来说所有问题相结合。
bcherry 2014年

1
这为我解决了不使用viewForKey的问题,但我想也应该使用。
凯文·斯利希

5
尽管这似乎可以解决问题,但需要注意的是,一旦显示,视图控制器后面的屏幕将变黑。如果您的视图控制器不是全屏显示,这一点很重要。
花花公子

16

我在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, 没有任何黑客!就像魔术!:)


1
这是实际的正确答案。没有被接受的魔术般的魔术。谢谢马克!
Andrei Malygin'7

不幸的是,这在iOS 12.4,Xcode 10.3中不起作用。屏幕变成过渡完成后,黑(所有视图已从层次结构中移除然而,“modalPresentationStyle”属性设置为“.fullscreen”并不工作的欢呼声。
旺布尔

我在项目中尝试了Mark和gwinyai的Swift实现中的Obj-C版本。不幸的是,它们都没有按预期工作。我正在使用Xcode 11.1,构建目标是iOS 13.0,我在设备和模拟器上都尝试过。就我而言,我的基本设置是一个集合视图,当您点击一个单元格时,它将选择带有动画的详细视图。但是,如果我使用默认的过渡动画,则效果很好。当我从视图的细节恢复时,当前的VC将不会消失。
infinity_coding7

8

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

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

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

返回值:

用于管理模式表示的自定义表示控制器。

讨论:

当您使用UIModalPresentationCustom表示样式表示视图控制器时,系统将调用此方法,并要求管理您的自定义样式的表示控制器。如果实现此方法,请使用它来创建并返回要用于管理演示过程的自定义演示控制器对象。

如果您未实现此方法,或者此方法的实现返回nil,则系统将使用默认的表示控制器对象。默认的表示控制器不会向视图层次结构添加任何视图或内容。

可用性在iOS 8.0和更高版本中可用。

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

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

WWDC中还有一个示例代码,名为“ LookInside:演示控制器自适应性和自定义动画对象”,您可以从WWDC 2014示例代码页中下载。

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

initWithPresentedViewController:presented presentingViewController:presenting

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


很抱歉没有观看链接的视频,但是除非您希望动画完成后想要一个非标准的演示文稿(例如圆形演示视图),否则我认为您不需要自定义UIPresentationController。如果您只想使用其他动画,则根据我的有限知识,实现UIViewControllerAnimatedTransitioning应该就足够了。
Vaddadi Kartick '17

7

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

if (self.presenting) {

    [transitionContext.containerView addSubview:toViewController.view];
    // your code

} else {
    // your code
}

您可以在此处看到一个示例:链接,它适用于iOS 7和iOS 8


这是做UIModalPresentationStyleCustom类型动画的公认答案,因为不需要将fromViewController添加到containerView。您只需要在演示动画期间添加toViewController。
Scott Kaiser 2014年

实际上,这非常有帮助
Dmitry Bondarev

7

这是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:]方法,以便从另一个视图控制器的解除完成块中展示一个新的视图控制器,以使其正常工作。

我不知道这会为每个人解决,但可以在我的应用程序中使用。干杯!


5

我发现这对于Obj-C很好用:

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

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


5

我发现viewForKey:UITransitionContextToViewKey在ios8 上返回nil。因此,如果它为零,则从“ to”视图控制器获取视图。

但是,这似乎导致“ to”视图在completeTransition:YES调用时不会从容器移动到窗口。因此,如果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];
        }
    }];
}

3

我发现,如果设置,此bug(以及更多!)将消失modalPresentationStyle = UIModalPresentationFullScreen。当然,您仍然可以获得自定义过渡动画。


2

我也被困在这个问题上。我一直在尝试创建一个具有半透明背景的自定义过渡,在那里我仍然可以看到我来自的视图控制器,但是我只有黑色背景。我发现Mark Aron在该线程中的答案对我有所帮助,但它是用Objective C编写的,因此,这是该答案的Swift 3版本,我已经为iOS 9和iOS 10测试过:

  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。这将为零,并且在运行时会出现错误。除此之外,如果您实现类似的东西,您将获得带有动画的自定义过渡,如果制作一个,则将获得半透明背景。


这个iis是在Swift 3中进行自定义模式演示的一个很好的例子!谢谢@gwinyai!直到发现一个示例展示新的swift 3 API的示例,我presentationController(forPresented presented UIViewController,... 才对此深深地迷住了,因为以前的swift API不会破坏编译器,但是没有被调用。
Natalia

2

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

一些答案提到更改modalPresentationStyle.overFullScreen。这是正确的,.overCurrentContext也可以。这是预期的,并且Apple记录了该行为。但是,为什么这对每个人都不起作用?为什么要使用所有骇客代码,以及这些代码与其他内容的组合以及您不应该做的疯狂的事情?

事实证明,您需要在VIEW LOADS之前设置演示样式。不后。只要在视图加载之前,就可以在init中执行此操作,或者从以前的控制器执行此操作,或者根据您的意愿进行操作。


1
我将表示样式设置为.overCurrentContext 在视图加载之前(在init视图控制器的中),并且问题仍然存在
ricardopereira

1

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


由于某些原因,这似乎不允许与下面的视图进行交互,而UIModalPresentationCurrentContext在iOS 7中是这样做的。
Christopher Wirt

对我来说,在iOS 10上,.overCurrentContext会导致此错误,但.fullscreen不会。我来到这里是为了寻求使用.overCurrentContext的修复程序,但到目前为止,似乎没有任何东西可以在iOS 10中正常工作,除非可以继承UIPresentationController ...
Natalia

0

好的,伙计们,我想我解决了一种情况,当您在iOS 13及更高版本中构建应用程序时,“有效的动画师”将无法正常工作。

Env Xcode 11.1,iOS 13.1

问题

我想做的事情很简单:我有一个集合视图,当点击一个单元格时,它将选择一个详细视图。我不想让枯燥的默认样式“模态呈现”,而是让它变得更有趣,所以我为视图控制器转换编写了一个动画器。

通过从集合VC拖放到详细信息VC,在IB中设置了segue。segue的样式为“模态呈现”,演示设置为“全屏”。

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

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

transitionContext.completeTransition(true)

2.只要明细视图没有完全覆盖收集视图,当从明细视图回退时,收集视图不会消失

老实说,我对动画过渡的工作原理知之甚少。因此,我只能按照这篇文章和另一篇文章,尝试每个答案。不幸的是,他们都不适合我。最终,我到达了一个唯一可以调整的地方,就是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”且仅间接起作用的方式,在另一篇文章中也提到了此问题,因此我认为值得在这里发布我的小发现。

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


0

解雇内容视图控制器时遇到同样的问题。

我的应用程序具有此父视图控制器,以模态方式显示子视图控制器(显示vc)。然后,当点击childVC中的子视图时,它显示另一个vc(我正在将其称为内容视图控制器(表示为vc))

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

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

  1. 改变.modalPresentationStyle的childVC呈现由parentVC从默认.automatic.fullscreen
  2. 然后将.modalPresentationStylecontentVC的也更改.fullscreen为。

这样就解决了问题。但不会将您的子级VC显示为parentVC上的卡片样式表(使用.overCurrentContext为在iOS 13中新增或自动)。

很想知道是否有任何解决方案可以在父级呈现时保留childVC的卡片样式表。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.