![](/img/trans.png)
[英]Black screen after presenting model view controller in current context from tab controller
[英]Black screen after presenting modal view controller in current context from UITabBarController
我的根视图控制器是一个 UITabBarController。 我正在尝试在选项卡栏控制器的视图控制器之一上显示模态视图控制器,但仍然允许使用选项卡栏转到不同的选项卡 - 换句话说,我希望模态仅中断该特定选项卡的流程,而不是整个应用程序。
为此,我在故事板中将呈现视图控制器的呈现样式设置为“Over Current Context”。 我遇到的问题是,在呈现模式视图控制器并选择一个新选项卡后,呈现视图控制器的视图将从窗口中删除,并且在关闭呈现的视图控制器时不会添加回窗口。 关闭视图控制器后,移动到另一个选项卡然后返回最终将呈现视图控制器放回窗口中。
我使用 Xcode 中的“Tabbed”模板重现了我的问题。
在呈现模态之后 - 我已经为呈现的视图控制器添加了透明度,以便轻松查看呈现的视图控制器中发生的事情。
更改为第二个选项卡然后返回 - 呈现视图控制器的视图现在已被删除。
关闭模态会使呈现视图控制器的视图仍然从窗口中移除。 转到选项卡 2 并返回将视图添加回窗口。
我希望这是我在故事板中忽略的一些简单的事情,但事实上我可以在更改选项卡之前展示模态并查看其背后呈现的视图控制器,这让我认为我已经正确设置了一些东西。
我有同样的问题,并且能够通过设置self.definesPresentationContext = YES;
来解决它self.definesPresentationContext = YES;
在呈现模态 VC 之前在呈现视图控制器上。 您也可以在故事板中设置它,该复选框在界面生成器中称为“定义上下文”。
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: {
})
}
全屏显示将您的视图控制器覆盖在您的标签栏(控制器)上。 因此,最终用户无法切换标签栏(除非您以编程方式执行操作)标签栏项目。 用户必须关闭此视图控制器才能切换标签栏。
如果您正在使用 segue,要呈现视图控制器,请从属性检查中的模态呈现样式中选择“全屏显示”
我遇到了这个问题:当我展示我的 ModalController 时,它需要透明背景,当我将选项卡更改为 tabBarController 中的下一个并返回上一个时,透明背景消失了,并且经过研究后黑色背景很糟糕,我发现了这一点重点是:
self 不是模态控制器 self 是为 modalController 呈现控制器,另一点是像这样的 .overCurrentContext
self.definesPresentationContext = true
modalController.modalPresentationStyle = .overCurrentContext
self.present(modalController, animated: true, completion: nil)
尝试在应用程序窗口中呈现视图控制器。 我有一个类似的问题,已通过以下代码修复:
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)
希望这对你也有帮助。
我重现了您的问题并找到了解决方案。 它不涉及更改 segue 方法或更改故事板中的某些属性。
建议:
但在进入解决方案之前,我想补充一点,模态呈现的视图控制器的目的是扰乱应用程序的实际流程,并为呈现的 vc 呈现一些额外的上下文信息或一些可操作的内容。 简单地说,这是非常合乎逻辑的,实际上建议在以模态方式呈现视图控制器时覆盖选项卡栏。 应用商店中有很多很好的例子。话虽如此,这是我提出的解决方案。
解决方案:
我相信问题在于 UITabBarController 处理其视图层次结构的方式。 我所做的是在更改选项卡之前明确关闭模态呈现的视图控制器。 这使得呈现视图控制器在选项卡栏切换到新选项卡之前一直保留在 UITabBarViewController 的视图层次结构中。在模态呈现的 ViewController 的“viewWillDisappear”方法中添加这个。
- (void)viewWillDisappear:(BOOL)animated { [self dismissViewControllerAnimated:true completion:^{ [super viewWillDisappear:animated]; }]; }
我的标签控制器有一个类似的问题,但是就像评论一样,我建议将转场更改为推送或显示转场。 这将允许该选项卡在切换到其他选项卡时与代替旧视图显示的新视图保持一致。 如果美学是一个问题,您可以制作一个自定义导航控制器来自定义新视图的外观。
我在当前的 swift 项目中遇到了同样的问题。 我已经解决了这个问题。
然后最后我使用了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)
}
它对我来说很好用。 我认为在选项卡更改事件上关闭视图控制器不是一个合适的解决方案,但是可以关闭而不是黑屏,这也会在那时破坏导航。
在调用 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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.