0
votes

I'm presenting a navigation controller (detailview) with showDetailViewController(). I want to dismiss it when a button is pressed. How can I dismiss this viewcontroller?

Code I've attempted:

//detailviewcontroller
    @objc
    func cancel(_ sender: Any) {
        print("cancelPressed")
        //self.navigationController?.popViewController(animated: true)
        //self.navigationController?.dismiss(animated: true, completion: nil)
        //self.dismiss(animated: true, completion: nil)
        //splitViewController?.dismiss(animated: true, completion: nil)
        //splitViewController?.navigationController?.popToRootViewController(animated: true)
        //splitViewController?.navigationController?.popViewController(animated: true)
        //splitViewController?.navigationController?.dismiss(animated: true, completion: nil)
        //navigationController?.popViewController(animated: true)
        //navigationController?.dismiss(animated: true, completion: nil)
        //self.navigationController?.popToRootViewController(animated: true)
        //self.navigationController?.viewControllers.remove(at: 1)
        //self.navigationController?.viewControllers.remove(at: 0) - this one removes to blank view
        //self.presentingViewController?.dismiss(animated: true, completion: nil)
    }

I've tried multiple stackoverflow solutions:

Dismissing a navigation view controller

How to dismiss a view controller in a navigation controller, without dismissing the whole stack

ios swift - dismiss root view controller of navigation controller

Can't dismiss View Controller that's embedded in a Navigation Controller

How to dismiss a navigation controller presented from another navigation controller in iOS 10 and below?

Can't dismiss navigation controller in Swift

Can't dismiss navigation controller in Swift

Dismissing View Controller Doesn't Work While Using Navigation Controller

Dismiss current navigation controller when clicked tab bar

How to dismiss a certain view controller

How I'm presenting the detailviewcontroller:

//masterviewcontroller
// delegation for passing data between controllers
weak var passDelegate: PlaceSelectionDelegate?

func insertNewObject(_ sender: Any) {
    if let detailViewController = passDelegate as? DetailViewController {
        if let detailNavigationController = detailViewController.navigationController {
            detailViewController.delegate = self
            splitViewController?.showDetailViewController(detailNavigationController, sender: nil)
        }
    }
}

Expected results: dismiss detail viewController on button press.

Actual results: No dismiss.

2
What should be visible in the detail side of the split view controller after dismissing the navigation controller?rmaddy

2 Answers

0
votes

Ok, I've been looking for a way of dealing with this showDetailViewController for a while now and although I'm not sure this answers your question, this is how I did it:

I have two controllers, let's call it FirstController and SecondController. They both inherit from UIViewController. When I click a certain navbar button in the FirstController, I use showDetailViewController to show SecondController as a sheet moving upwards, like the "calendars" button in the Calendar app.

In FirstController I implemented 2 functions: one to show the SecondController and one to dismiss it. I call the dismiss action from within the SecondController. It looks like this:

// FirstController
@objc func showSecondView() {
    let vc = SecondController()
    vc.delegate = self          
    let nav = UINavigationController(rootViewController:vc)            
    self.showDetailViewController(nav, sender: self)
}

func closeSecondView() {
    self.dismiss(animated: true)
}

As you can see I wrapped my SecondController in a UINavigationController, so it shows the navbar with title and all. This is how the code looks like:

// SecondController
weak var delegate: FirstController!

override func viewDidLoad() {
    super.viewDidLoad()
    title = "Second"
    navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(closeMe))
}

@objc func closeMe() {
    delegate.closeSecondView()
}

Notice how I made a property for the FirstController and I use it to dismiss the SecondController. When I presented SecondController I assigned self as delegate, which means I can now call the closeSecondView method from within it.

I am not sure whether it works out of the box with split-view. The documentation seems to suggest that whenever you use it, if the screen is big enough, it behaves differently because UISplitViewController overrides it. It also says there that all view controllers have this method.

Take a look: https://developer.apple.com/documentation/uikit/uiviewcontroller/1621432-showdetailviewcontroller

Give it a go, I hope this helps.

-1
votes

This should work if you simply want to dismiss the navigation controller

navigationController?.dismiss(animated: true, completion: nil)