【发布时间】:2020-02-24 19:13:49
【问题描述】:
我有一个带有两个标签的UITabBarViewController。我想在其中一个选项卡中全屏显示 viewController。我使用了以下代码。
let navCtrl = UINavigationController(rootViewController: eventViewController)
navCtrl.modalPresentationStyle = .fullScreen
self.navigationController?.present(navCtrl, animated: true)
它有效。 EventViewController 是全屏的。但是,当在EventViewController 中呈现另一个viewController 时,EventViewController 仍然是全屏的。但我希望它像往常一样缩小尺寸和堆叠(如图所示)。为此,我将modalPresentationStyle 更改为overCurrentContext。
let navCtrl = UINavigationController(rootViewController: eventViewController)
navCtrl.modalPresentationStyle = .overCurrentContext
self.navigationController?.present(navCtrl, animated: true)
这样做,但它会导致另一个问题:如果我更改选项卡并关闭 EventViewController,则呈现的 viewController 是 black,如 question 中所述(没有一个答案有帮助) em>。
基本上我希望EventController 是全屏的,但在其中显示另一个控制器时会缩小尺寸。怎么做?
更新
一个具有相同问题的简单项目。
class TabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
let ctrl = TabZeroViewController()
ctrl.tabBarItem.image = UIImage(named: "archived-task")
ctrl.tabBarItem.title = "One"
let test = TabOneViewController()
test.tabBarItem.image = UIImage(named: "Test")
test.tabBarItem.title = "Test"
let tabBarList = [ctrl, test ]
self.viewControllers = tabBarList.map {
let nav = UINavigationController(rootViewController: $0)
nav.interactivePopGestureRecognizer?.isEnabled = true
return nav
}
}
}
class TabZeroViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.delegate = self
self.tableView.dataSource = self
self.view.backgroundColor = .white
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = "\(indexPath.row)"
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let ctrl = ModalTableViewController()
let nav = UINavigationController(rootViewController: ctrl)
nav.modalPresentationStyle = .fullScreen
self.navigationController?.present(nav, animated: true)
}
}
class ModalTableViewController: UITableViewController {
override func viewDidLoad() {
self.view.backgroundColor = .red
let button = UIButton()
button.setTitle("Cancel", for: .normal)
button.addTarget(self, action: #selector(dismissModal), for: .allEvents)
let item = UIBarButtonItem()
item.customView = button
self.navigationItem.leftBarButtonItem = item
self.tableView.dataSource = self
self.tableView.delegate = self
}
@objc func dismissModal() {
self.dismiss(animated: true, completion: nil)
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = "Event"
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let ctrl = EventViewController()
let nav = UINavigationController(rootViewController: ctrl)
nav.modalPresentationStyle = .overCurrentContext
self.navigationController?.present(nav, animated: true)
}
}
class TabOneViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
}
class EventViewController: UITableViewController {
override func viewDidLoad() {
self.view.backgroundColor = .red
let button = UIButton()
button.setTitle("Cancel", for: .normal)
button.addTarget(self, action: #selector(dismissModal), for: .allEvents)
let item = UIBarButtonItem()
item.customView = button
self.navigationItem.leftBarButtonItem = item
self.tableView.dataSource = self
self.tableView.delegate = self
}
@objc func dismissModal() {
self.dismiss(animated: true, completion: nil)
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = "Event"
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let ctrl = EventViewController()
let nav = UINavigationController(rootViewController: ctrl)
self.navigationController?.present(nav, animated: true)
}
}
将此代码添加到willConnectTo 中的SceneDelegate。
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = TabBarController()
self.window = window
window.makeKeyAndVisible()
}
当您在第一个选项卡上时,选择一个表格单元格以打开 ModalTableViewController。然后更改标签并关闭ModalTableViewController。
【问题讨论】:
-
首先,您需要更新导航控制器中的视图控制器,但导航控制器旨在用于推送视图控制器。因为它可能会导致意外行为。
-
我已经运行了相同的流程并且它按预期工作。有一件事要问:以 EventViewController 为根的导航控制器没有显示在整个屏幕上,您如何在显示时更改选项卡。请向我澄清这一点。
-
您确实提供了一个导航控制器,当您关闭任何不会关闭附加的导航控制器的控制器时,这就是您面临黑屏问题的原因。
-
@neerajjoshi,按照以下步骤操作,1. 设置
modalPresentationStyle = .overCurrentContext2. 呈现 viewCtrl 3. 选择另一个选项卡,然后选择相同的选项卡。 4 关闭呈现的viewCtrl。 -
@mahan ,我可以玩一下你的源代码吗?如果是,那么您可以创建具有此类场景的示例项目并上传到 GitHub。
标签: ios swift uiviewcontroller