从UITabBarController在当前上下文中呈现模态视图控制器后的黑屏

时间:2015-01-05 18:18:09

标签: ios objective-c iphone uikit

我的根视图控制器是一个UITabBarController。我试图在其中一个标签栏控制器的视图控制器上显示一个模态视图控制器,但仍然允许使用标签栏转到另一个标签 - 换句话说,我想要模式只能中断特定选项卡的流程,而不是整个应用程序。

为此,我将呈现视图控制器的演示风格设置为“当前上下文”#39;在故事板中。我遇到的问题是,在呈现模态视图控制器并选择新选项卡后,呈现视图控制器的视图将从窗口中移除,并且在解除时不会添加回窗口呈现的视图控制器。在关闭视图控制器后,移动到另一个选项卡然后返回最终将呈现视图控制器放回窗口。

我使用“Tabbed”'重现了我的问题。 Xcode中的模板。

在呈现模态之后 - 我已经为所呈现的视图控制器添加了透明度,以便轻松查看所呈现的视图控制器中发生了什么。

更改为第二个标签然后返回 - 现在已删除了呈现视图控制器的视图。

关闭模态会使呈现视图控制器仍然从窗口中删除它的视图。转到选项卡2并返回将视图添加回窗口。

我希望这是一个简单的事情我在故事板中被忽略了,但事实上我可以在更改标签之前呈现模态并在其后面看到呈现的视图控制器让我觉得我已经设置好了正确。

9 个答案:

答案 0 :(得分:37)

我遇到了同样的问题,并且能够在呈现模式VC之前通过在呈现视图控制器上设置self.definesPresentationContext = YES;来解决它。您也可以在故事板中设置它,复选框称为"定义上下文"在Interface Builder中。

答案 1 :(得分:11)

iOS 10+& Swift 3 +

我很好地解决了这个问题。正在呈现用于视图控制器的全屏模式演示样式。

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: { 
            })
        }

全屏将通过覆盖标签栏(控制器)显示您的视图控制器。因此,最终用户无法切换标签栏(除非您以编程方式执行操作)tabbar项目。用户必须关闭此视图控制器才能切换标签栏。

如果您使用segue,则显示视图控制器,然后从属性检查中的模态显示样式中选择“全屏幕”

答案 2 :(得分:10)

尝试在故事板中将演示文稿样式设置为“全屏幕”而不是“过度上下文”。 enter image description here

答案 3 :(得分:6)

尝试在应用程序窗口中显示视图控制器。我有一个类似的问题,由以下代码修复:

    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)

希望这对你也有帮助。

答案 4 :(得分:4)

我重现了你的问题并找到了解决方案。 它不涉及更改segue方法或更改故事板中的某些属性。

<强>建议:

但在进入解决方案之前,我想补充一点,模态呈现的viewcontrollers的目的是破坏应用程序的实际流程,并为呈现vc提供一些额外的上下文信息或一些可操作的内容。简单地说,它是非常合乎逻辑的,实际上建议在模式化呈现视图控制器时覆盖标签栏。在应用程序商店中有很多很好的例子。

说完这里是我提出的解决方案。

<强>解决方案:

我认为问题在于UITabBarController处理其视图层次结构的方式。

我做的是在更改选项卡之前明确地解除模态呈现的视图控制器。这使得呈现视图控制器在标签栏切换到新选项卡之前保持在UITabBarViewController的视图层次结构中。

在模态呈现的ViewController的“viewWillDisappear”方法中添加此内容。

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

答案 5 :(得分:4)

我遇到了这个问题:当我呈现我的ModalController时,它需要透明背景,当我将标签更改为tabBarController中的下一个标签并将getBack更改为上一个标签时,透明背景消失了,并且在我发现研究之后有一个糟糕的黑色背景重点是:

self.definesPresentationContext = true

自我不是模态控制器自我是为modalController呈现控制器而另一个点是.overCurrentContext就像这样

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

答案 6 :(得分:1)

我的标签控制器出现类似问题,但是就像评论一样,我建议将segue更改为push或show segue。当切换到其他选项卡时,这将允许该选项卡保持与显示的新视图代替旧视图。如果美学是个问题,您可以制作自定义导航控制器来自定义新视图的外观。

答案 7 :(得分:0)

我在目前的直播项目中遇到同样的问题。我已经解决了这个问题。

然后最后我使用NSNotificationCenter并在更改选项卡以解决​​此问题时忽略该视图控制器。

我在AppDelegate中引用了tabbar控制器并在那里设置了委托。

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)
    }
}

然后我将观察者添加到我呈现的视图控制器中

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)
}

它对我来说很好。不是一个合适的解决方案我认为在选项卡更改事件中关闭视图控制器,但是可以解雇而不是黑屏,这也会打破导航时间。

答案 8 :(得分:0)

在调用ViewController之前,我还需要一个导航控制器

我以前使用过描述的代码:

let newVC = self.storyboard?.instantiateViewController(withIdentifier: "newViewController")
        self.definesPresentationContext = true
        self.providesPresentationContextTransitionStyle = true
        newVC?.modalPresentationStyle = .overCurrentContext //do NOT use .currentContext --> it will produce a black screen by switching over tabbar and close VC
        self.present(newVC!, animated: false)