iOS 8-在关闭具有自定义演示的视图控制器后屏幕空白


68

使用关闭各种视图控制器时,关闭视图控制器后UIModalPresentationCustom,屏幕将变黑,就好像所有视图控制器都已从视图层次结构中删除一样。

正确设置了过渡委托,要求并正确传递animationControllerForPresentedController,并且一旦动画结束,过渡就完成了。

使用iOS 7 SDK编译时,此确切的代码可以完美地工作,但使用iOS 8b5编译时,该代码会损坏


我正在使用Xcode 6 GM,除了屏幕为白色(我的窗口具有白色背景色)以外,其他行为均类似。代码在iOS 7中工作正常。我使用Reveal检查了视图,窗口只是空的。
2014年

Xcode 6 GM在这里也看到相同的行为。使用内置的视图展开器,过渡后我只能找到一个UIWindow和UITextEffectsWindow。其他一切都消失了。
凯文·斯利希

Answers:


184

这是因为您很可能同时添加两个演示文稿

[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]

和提出

[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]

在您的动画控制器的(void)animateTransition:(id)transitionContext方法中查看容器的控制器。由于您使用的是自定义模式演示,因此呈现视图控制器仍显示在呈现的视图控制器下方。现在,由于它仍然可见,因此您无需将其添加到容器视图中。而是仅将提供的视图控制器添加到containerView。应该在animateTransition:方法内部看起来像这样

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

// Boolean value to determine presentation or dismissal animation
if (self.presenting){        
    [transitionContext.containerView addSubview:toViewController.view];
    // Your presenting animation code
} else {
    // Your dismissal animation code
}

12
这是正确的答案,应该接受。iOS 7中存在一个错误,该错误已在iOS 8中修复。以上解决方案在iOS 7和8上均能完美运行。感谢DJSK指出这一点,花了一些时间弄清楚如何获得空白屏幕。
Stas Zhukovskiy 2014年

1
我同意@StasZhukovskiy的观点。这样就解决了问题。我发现的剩下的一个问题是,iOS7.0中存在的/已解散的ViewController泄漏,尽管不是7.1或8。...–
Mike Pollard

3
显然这不是正确的答案-根据UIViewControllerContextTransitioning标题,我们应该使用-viewForKey方法来获取视图。不幸的是,在某些情况下,UIModalPresentationCustom原因导致的表示形式-viewForkey为零,这显然是所需的行为....bcherry此处查看答案。
DanZimm 2015年

1
@DanZimm使用[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey] .view或[transitionContext viewForKey:UITransitionContextFromView]都没有关系。他们是完全一样的东西。使用自定义模式过渡时的问题是(在iOS8中)如果将fromView添加到动画控制器中,则动画完成后它不会返回到原始层次结构。您可以在以后手动返回它,也可以选择根本不添加它。
Scott Kaiser

1
@DJSK您的帖子在那里回答了我的其他问题吗?谢谢
Colas 2015年

20

这种高票赞成的答案会误导人们。长话短。

首先,不要使用UIModalPresentationCustom,这听起来并不像。(详细

其次,有一种新方法可以在animateTransition中从视图中检索/到视图,不再使用诸如'fromVC.view'之类的东西。(为什么

UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];

//swift
let fromVC = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)
let toVC = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)
let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)
let toView = transitionContext.viewForKey(UITransitionContextToViewKey)

现在黑屏应该消失了。


如果您要针对特定​​版本的iOS(例如8或更高版本)进行开发,那么这绝对是实现此目标的正确方法。我提供的答案只是实现相同功能的一种简便方法,而无需检查或具体说明,同时还可以容纳iOS7。
Scott Kaiser

如何获得transitionContext?
阿妮塔


2

我将下面的代码添加到过渡完成块中,并为我修复了它。

[UIView animateWithDuration:[self transitionDuration:transitionContext] animations: ^{
    // Animation code

 } completion: ^(BOOL finished) {
     // More of your code

     // Add the following line before completing the transition
    [[[UIApplication sharedApplication] keyWindow] sendSubviewToBack:toViewController.view];

    // Complete the transition
    [transitionContext completeTransition:YES];
}];

2

可能视图层次结构与新的Xcode无关,或者与iOS8有所不同。这段代码对我有用。在animateTransition:transitionContext方法中关闭控制器时添加它。

[[UIApplication sharedApplication].keyWindow addSubview:toViewController.view];
toViewController.view.userInteractionEnabled = YES;

1
它可能不是iOS中的错误,而是我们自己的代码。您是否将modalPresentationStyle设置为UIModalPresentationCustom,但未实现presentationControllerForPresentedViewController方法?看到这里:stackoverflow.com/a/25655575/466965
Lcsky

0

快速提示:确保您的“ From” UIViewController是您所期望的。

    NSLog(@" FROM vc %@" , [[transitionContext  viewControllerForKey:UITransitionContextFromViewControllerKey] description]);

过去,我的代码中也有类似的错误。您可以轻松地提取正确的“ From” VC上下文。

  UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];  
  fromView =  [[[fromVC childViewControllers] firstObject]  view];

0

我有同样的问题,对我来说造成问题的是我没有设置toViewController的最后一帧。请参见http://www.appcoda.com/custom-view-controller-transitions-tutorial/中的以下示例

func animateTransition(transitionContext: UIViewControllerContextTransitioning) {

    let fromViewController = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)!
    let toViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)!
    let finalFrameForVC = transitionContext.finalFrameForViewController(toViewController)
    let containerView = transitionContext.containerView()
    let bounds = UIScreen.mainScreen().bounds
    toViewController.view.frame = CGRectOffset(finalFrameForVC, 0, bounds.size.height)
    containerView.addSubview(toViewController.view)

    UIView.animateWithDuration(transitionDuration(transitionContext), delay: 0.0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.0, options: .CurveLinear, animations: {
        fromViewController.view.alpha = 0.5
        toViewController.view.frame = finalFrameForVC
    }, completion: {
        finished in
        transitionContext.completeTransition(true)
        fromViewController.view.alpha = 1.0
    })
} 
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.