web-dev-qa-db-ja.com

iOS 8-カスタムプレゼンテーションでView Controllerを閉じると画面が空白になる

UIModalPresentationCustomを使用してさまざまなView Controllerを閉じると、すべてのView Controllerがビュー階層から削除されたかのように、View Controllerが閉じられた後に画面が黒くなります。

遷移するデリゲートが適切に設定され、animationControllerForPresentedControllerが要求されて正しく渡され、アニメーションが終了すると遷移が完了します。

この正確なコードは、iOS 7 SDKでコンパイルすると完全に機能しますが、iOS 8b5でコンパイルすると壊れます。

65
jaggedcow

これは、プレゼンテーションと

[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]

そして提示された

[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]

アニメーションコントローラーの(void)animateTransition:(id)transitionContextメソッドでcontainerViewにコントローラーを表示します。カスタムモーダルプレゼンテーションを使用しているため、presenting view controllerpresented view controllerの下に表示されたままです。まだ表示されているため、コンテナビューに追加する必要はありません。代わりに、表示されたView Controllerのみを追加 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
}
174
Scott Kaiser

これは、高得票と受け入れられた回答が人々を誤解させるような質問です。長い言葉は短い。

まず、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)

これで黒い画面が消えます。

19
Lcsky

Xcode 6 beta5を使用しているのと同じ問題が発生したようです。

Googleで検索したところ、他の誰かが同じ問題を抱えていることがわかりましたが、これはiOS 8の深刻なバグであるため、Appleがすぐに修正できると期待しています。

https://github.com/TeehanLax/UIViewController-Transitions-Example/issues/5

5
billbai

おそらく、ビュー階層は新しいXcodeでバグがあるか、iOS8で少し異なるかもしれません。このコードはうまくいきました。 animateTransition:transitionContextメソッドでコントローラーを閉じながら追加します。

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

以下のコードを遷移完了ブロックに追加し、修正しました。

[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
devgeek

私も同じ問題を抱えていましたが、問題の原因は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
    })
} 
0
eliasbagley

クイックヒント:「From」UIViewControllerが期待どおりであることを確認してください。

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

過去に私のコードに同様のバグがありました。正しい「From」VC context。

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