web-dev-qa-db-ja.com

UITabBarControllerから現在のコンテキストでモーダルビューコントローラーを表示した後の黒い画面

私のルートビューコントローラーはUITabBarControllerです。私はTab Bar ControllerのView Controllerの1つにモーダルView Controllerを表示しようとしていますが、Tab Barを使用して別のタブに移動できます-つまり、モーダルは中断するだけですアプリ全体ではなく、その特定のタブのフロー。

これを行うために、ストーリーボードで表示するView Controllerの表示スタイルを「Over Current Context」として設定しました。私が抱えている問題は、モーダルビューコントローラーを表示して新しいタブを選択した後、表示しているビューコントローラーのビューがウィンドウから削除され、表示されたビューコントローラーを閉じるときにウィンドウに追加されないことです。 View Controllerを閉じた後、別のタブに移動してから戻ると、表示中のView Controllerがウィンドウに戻ります。

Xcodeの「Tabbed」テンプレートを使用して問題を再現しました。

モーダルを提示した後-提示されたView Controllerで透明度を追加して、提示されたView Controllerで何が起こっているかを簡単に確認しました。

2番目のタブに変更してから戻る-表示するView Controllerのビューは削除されました。 

モーダルを閉じると、ビューはウィンドウから削除されたままの状態で、表示するView Controllerを残します。タブ2に移動して戻ると、ビューがウィンドウに追加されます。 

これがストーリーボードで見落としていたシンプルなものであることを願っていますが、タブを変更する前にモーダルを提示し、その背後に提示されたView Controllerを見ることができるという事実は、私が物事を正しく設定していると思うようにします。

41
alivingston

私は同じ問題を抱えていたので、self.definesPresentationContext = YES;モーダルVCを提示する前の提示View Controller上。ストーリーボードでこれを設定することもできます。チェックボックスは、Interface Builderで「コンテキストを定義」と呼ばれます。

36
Ole Begemann

ストーリーボードでプレゼンテーションのスタイルを「現在のコンテキストを超える」の代わりに「フルスクリーンを超える」に設定してみてください。 enter image description here

13
malajisi

iOS 10以降&Swift 3 +

私はこの問題の非常に素晴らしい解決策を持っています。 View Controllerのフルスクリーンモーダルプレゼンテーションスタイルでの使用が提示されています。

let storyboard = UIStoryboard(name: "Main", bundle: nil)  // Replace “Main” with your storyboard name

if let viewController = storyboard?.instantiateViewController(withIdentifier: “viewController Identifier”) as? ViewController {
            viewController.modalPresentationStyle = .overFullScreen
            self.present(viewController, animated: false, completion: { 
            })
        }

全画面表示すると、View ControllerがTabbar(コントローラー)の上に隠れて表示されます。したがって、エンドユーザーは、タブバー項目を(プログラムで操作を実行しない限り)タブバーに切り替えることはできません。ユーザーは、このView Controllerを閉じてTabbarを切り替える必要があります。

セグエを使用している場合、View Controllerを表示するには、属性検査のモーダル表示スタイルから「オーバーフルスクリーン」を選択します

13
user7620770

アプリケーションウィンドウにView Controllerを表示してみてください。以下のコードで修正された同様の問題がありました:

    let myNewVC = mainStoryBoard.instantiateViewController(withIdentifier: "MyNewVCId") as! MyNewVC
    let navController = UINavigationController(rootViewController: myNewVC)
    navController.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext    

    let appDelegate = UIApplication.shared.delegate as? AppDelegate
    appDelegate?.window?.rootViewController?.present(navController, animated: true, completion: nil)

これがあなたにも役立つことを願っています。

6
Shobhit C

私はこの問題を抱えていました:ModalControllerを提示すると、透明な背景が使用され、tabBarControllerで次のタブに変更し、前のタブにgetBackすると、透明な背景がなくなり、調査後に黒の背景が悪くなり、ポイントが見つかりましたポイントはこれです:

self.definesPresentationContext = true

selfはモーダルコントローラーではありませんselfはmodalControllerのコントローラーを提示し、別のポイントはこのような.overCurrentContextです

** self.definesPresentationContext = true ** modalController.modalPresentationStyle = .overCurrentContext self.present(modalController, animated: true, completion: nil)

5
jamal zare

問題を再現し、解決策を見つけました。セグエ手法の変更や、ストーリーボードの一部の属性の変更は含まれません。

提案:

これが私が提案する解決策であると言った。

解決策:

モーダル表示されたViewControllerの「viewWillDisappear」メソッドでこれを追加します。

- (void)viewWillDisappear:(BOOL)animated {
    [self dismissViewControllerAnimated:true completion:^{
    [super viewWillDisappear:animated];
  }];
}
5
saugat gautam

ただし、コメントのように、タブコントローラーで同様の問題がある場合は、セグエをプッシュまたはショーセグエに変更することをお勧めします。これにより、他のタブに切り替えたときに、古いビューの代わりに表示される新しいビューでそのタブがそのまま表示されます。美観が問題になる場合は、カスタムナビゲーションコントローラーを作成して、新しいビューの外観をカスタマイズできます。

1

現在ライブSwiftプロジェクトに同じ問題があります。これを回避しました。

最後にNSNotificationCenterを使用し、この問題を解決するためにタブが変更されたときにそのView Controllerを閉じました。

AppDelegateでTabbar Controllerを参照し、そこにデリゲートを設定しました。

let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)

let tabbarcontroller = storyboard.instantiateViewControllerWithIdentifier("MyTabBarController") as! UITabBarController

tabbarcontroller.delegate = self

そして、それは

//MARK: - Tabbar controller delegate

extension AppDelegate : UITabBarControllerDelegate {

    func tabBarController(tabBarController: UITabBarController, didSelectViewController viewController: UIViewController) {

        NSNotificationCenter.defaultCenter().postNotificationName("TabBarTabChanged", object: nil)
    }
}

次に、提示されたView Controllerにオブザーバーを追加します

override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(PreviewPlaceVC.BackClickAction(_:)), name: "TabBarTabChanged", object: nil)
}

// MARK: - Button Click Actions

@IBAction func BackClickAction(sender: AnyObject) {
     self.dismissViewControllerAnimated(true, completion: nil)
}

そして、それは私にとってはうまくいきます。適切な解決策ではありません。タブ変更イベントでView Controllerを閉じると思いますが、黒い画面ではなく、閉じることもできます。

0
Max