2

Learning some view controller basics and am stuck on how to dismiss a modal with a button.

In my slimmed-down example, I have a two view setup with the initial view and the modal. The first view has a button that successfully pops up the modal. On the modal, there is a button that should dismiss itself.

According to other posts and documentation, I should be able to run simple code attached to the button like this:

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func CloseModal(_ sender: Any) {
        self.dismiss(animated: true, completion: nil)
    }

}

When I tap the "Close Modal" button nothing happens. What am I missing here? Am I putting this code in the wrong place? Currently, it's in the main ViewController.swift file.

enter image description here

Sam
  • 2,152
  • 6
  • 31
  • 44

2 Answers2

6

The other approach is to use an unwind segue to your main view controller. Just add an “unwind action” in the first view controller:

class ViewController: UIViewController {

    @IBAction func unwindHome(_ segue: UIStoryboardSegue) {
        // this is intentionally blank
    }

}

Just give this unwind action a meaningful name, unwindHome in this example, so that, if and when you have multiple unwind actions later on, you can easily differentiate between them.

Then you can control-drag from the button in the second scene to the “exit” control and select the appropriate unwind action:

hook up exit outlet

This has a few nice aspects:

  • The “close” button no longer cares how you presented it, it will unwind however is appropriate (e.g. if you later change the initial segue to be a show/push segue, the unwind segue will still work without any code changes).

  • Because you’re now using a segue to unwind, the presented view controller can use its prepare(for:sender:) to send data back, should you eventually need to do that.

  • If you want, you can unwind multiple scenes. For example if A presents B, and B presents C, you can obviously unwind from C to B, but you can also unwind all the way from C to A if you want.

So, while dismiss works, unwind segues are another alternative.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
2

You actually have two ViewController screens, but it looks like you have one ViewController class? And is the 2nd screen connected to a class?

Must be in the class that belongs to the second screen of the closeModal method.

//This is First ViewController, OpenModal Button is here
class ViewController: UIViewController {

  override func viewDidLoad() {
     super.viewDidLoad()
  }

}


// The name of the class and the Viewcontroller in the storyboard have to be the same, and CloseModol Button and function need to be here 
class SecondViewController: UIViewController {

  override func viewDidLoad() {
     super.viewDidLoad()
  }

  @IBAction func CloseModal(_ sender: Any) {
     self.dismiss(animated: true, completion: nil)
  } 

}

Don't forget to set the name of the ViewController in Storyboad; from FirstViewController to SecondViewController

Baran Gungor
  • 176
  • 8
  • Yes. This is it. *Sigh…* I have so much to learn. Thank you. One other question: even though animated is set to true, there is no animation upon dismiss. The modal just disappears. I would have expected it to slide down (the opposite of how it slid up into view). Any ideas? – Sam May 18 '20 at 15:43