Stack fullscreen viewController when presenting another viewController

I had asked this question long times ago on StackOveflow. You may read it there since it is more readble and includes images




I have a

UITabBarViewController
with two tabs. I want to present a viewController fullscreen in one of the tabs. I have used the following code to do so.



  let navCtrl = UINavigationController(rootViewController: eventViewController)
  navCtrl.modalPresentationStyle = .fullScreen  
  self.navigationController?.present(navCtrl, animated: true)



It works. And

EventViewController
is fullscreen. However, when presenting another viewController in
EventViewController
,
EventViewController
is still fullscreen. But I want it to shrink in size and stack-up as it normally do. In order to do so, I have changed
modalPresentationStyle
to
overCurrentContext


  let navCtrl = UINavigationController(rootViewController: eventViewController)
  navCtrl.modalPresentationStyle = .overCurrentContext  
  self.navigationController?.present(navCtrl, animated: true)



It does so, but it causes another problem: If I change tabs and dismiss

EventViewController
, the presenting viewController is
black
as described in this question (none of the answers helped).



Basically I want the

EventController
to be fullscreen but shrink in size when presenting another controller in it. How to do so?


A simple project with the same issue.



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



Add this code in

willConnectTo
of
SceneDelegate


if let windowScene = scene as? UIWindowScene {
  let window = UIWindow(windowScene: windowScene)
  window.rootViewController = TabBarController()
  self.window = window
  window.makeKeyAndVisible()
}



While you are on first tab, select a table cell to open the

ModalTableViewController
. And then change tabs and dismiss
ModalTableViewController

Replies

However, when presenting another viewController in

EventViewController
,
EventViewController
is still fullscreen. But I want it to shrink in size and stack-up as it normally do.


Did you try to change the presentation mode of the other controller ? May be easier in IB, otherwise try to do it in viewDidLoad

Thanks.


If you mean changing the modalPresentationStyle of ModalTableViewController to formSheet, i did so.


Before presenting

EventViewController,
I used the following line of code.



self.navigationController?.modalPresentationStyle = .formSheet



It did not work.

That was not my suggestion.


It was to change in the destination controller, by inserting in viewDidLoad

        self.modalPresentationStyle = .fullScreen

Yes. I used the following line of code in ViewDidLoad of EventViewController. It did not work.


self.modalPresentationStyle = .fullScreen

`