How to pass data from modal view controller back when dismissed

I’ve followed the instructions here but I’m still unsure about this part:

modalVC.delegate=self;
        self.presentViewController(modalVC, animated: true, completion: nil) 

I’ve tried instantiating the view controller programmatically but still to no avail.

  • UITextField's numerical pad: dot instead of comma for float values
  • Issue with captureStillImageAsynchronouslyFromConnection for Back camera
  • Converting Int to Float loses precision for large numbers in Swift
  • Customizing the iOS permission dialog for push notifications
  • Programmatically Dial a Phone number and pass DTMF using the iPhone SDK
  • video thumbnail image not generated from local video URL(asset URL) iOS
  • here’s my code for when dismissing the modal view controller:

    @IBAction func dismissViewController(_ sender: UIBarButtonItem) {
            self.dismiss(animated: true) { 
                //
            }
        }
    

    I’m using storyboard to segue with modal view.

    This is the data I wish to transfer back to the parent view controller:

    var typeState = "top"
     var categoryState = "casual"
    

    Which are two String values.

    Edit:

    I’ve tried to pass data from the modal view controller as shown:

    @IBAction func dismissViewController(_ sender: UIBarButtonItem) {
            self.dismiss(animated: true, completion: nil)
            delegate?.sendValue(value: "success")
            if let presenter = presentingViewController as? OOTDListViewController {
                presenter.receivedValue = "test"
            }
        }
    

    whereas on the parent view controller I did as such:

    func sendValue(value: NSString) {
            receivedValue = value as String
        }
      @IBAction func printReceivedValue(_ sender: UIButton) {
            print(receivedValue)
        }
    

    I still couldnt receive any value when I hit the print button.

    Modal view controller:

    protocol ModalViewControllerDelegate
    {
        func sendData(typeState: String, categoryState: String)
    }
    
    var delegate:ModalViewControllerDelegate!
    
    var typeState = "top"
    var categoryState = "casual"
    @IBAction func dismissViewController(_ sender: UIBarButtonItem) {
            self.dismiss(animated: true, completion: nil)
            delegate?.sendData(typeState: typeState as String, categoryState: categoryState as String)
    
        }
    

    Parent view controller:

    class parentViewController: UICollectionViewController, ModalViewControllerDelegate {
    
    var typeState: String?
    var categoryState: String?
    func sendData(typeState: String, categoryState: String) {
            self.typeState = typeState as String
            self.categoryState = categoryState as String
        }
     @IBAction func printReceivedValue(_ sender: UIButton) {
         print(typeState)
     }
    

    Edit:

    Here’s my new code without using delegate method:

    Modal view Controller:

    @IBAction func dismissViewController(_ sender: UIBarButtonItem) {
            self.dismiss(animated: true, completion: nil)
            if let presenter = presentingViewController as? OOTDListViewController {
                presenter.typeState = typeState
                presenter.categoryState = categoryState
            }
        }
    

    OOTDListViewController:

    @IBAction func presentModalView(_ sender: UIBarButtonItem) {
            let modalView = storyboard?.instantiateViewController(withIdentifier: "filterViewController") as! ModalViewController
            let navModalView: UINavigationController = UINavigationController(rootViewController: modalView)
            self.present(navModalView, animated: true, completion: nil)
        }
    @IBAction func printValue(_ sender: UIButton) {
            print(typeState)
            print(categoryState)
        }
    

    2 Solutions Collect From Internet About “How to pass data from modal view controller back when dismissed”

    Depending on the data you want to pass, you can create a property in the presenting view controller, which you can set when dismissing the modal view controller, so you can spare yourself the delegate.

    For example, you have a ContactsViewController, holding a var contacts: [Contact] = [] property. When you want to create a new contact, you present a modal view controller with the different values you need to create a new Contact object. When you are done and want to dismiss the view controller, you call the function as you did in your code, but set the property in the ContactsViewController. It will look something like this:

    @IBAction func dismissViewController(_ sender: UIBarButtonItem) {
        if let presenter = presentingViewController as? ContactsViewController {
            presenter.contacts.append(newContact)
        }
        dismiss(animated: true, completion: nil)
    }
    

    EDIT:

    If you don’t want to use a delegate, this is how you go about it:

    In your OOTDListViewController :

    var testValue: String = ""
    
    @IBAction func printReceivedValue(_ sender: UIButton) {
        print(testValue)
    }
    

    In your modal view controller (I’ll call it PresentedViewController) :

    @IBAction func dismissViewController(_ sender: UIBarButtonItem) {
        // if your OOTDListViewController is part of a UINavigationController stack, this check will probably fail. 
        // you need to put a breakpoint here and check if the presentingViewController is actually a UINavigationController.
        // in that case, you will need to access the viewControllers variable and find your OOTDListViewController
        if let presenter = presentingViewController as? OOTDListViewController {
            presenter.testValue = "Test"
        }
        dismiss(animated: true, completion: nil)
    }
    

    If you want to use a delegate, this is how to do it:

    In your OOTDListViewController:

    protocol ModalDelegate {
    func changeValue(value: String)
    }
    
    class OOTDListViewController: ModalDelegate {
    
    var testValue: String = ""
    @IBAction func presentViewController() {
        // here, you either create a new instance of the ViewController by initializing it, or you instantiate it using a storyboard. 
        // for simplicity, I'll use the first way
        // in any case, you cannot use a storyboard segue directly, bevause you need access to the reference of the presentedViewController object
        let presentedVC = PresentedViewController() 
        presentedVC.delegate = self
        present(presentedVC, animated: true, completion: nil)
    }
    
    func changeValue(value: String) {
         testValue = value
         print(testValue)
    }
    

    }

    In your PresentedViewController:

    class PresentedViewController {
        var delegate: ModalDelegate? 
        var testValue: String = ""
    
        @IBAction func dismissViewController(_ sender: UIBarButtonItem) {
           if let delegate = self.delegate {
                delegate.changeValue(testValue)
            }
            dismiss(animated: true, completion: nil)
        }
    
    }
    

    You need to call the delegate method in dismissViewController method

    @IBAction func dismissViewController(_ sender: UIBarButtonItem) {
            delegate?.sendData(typeState: "top", categoryState: "casual")
            self.dismiss(animated: true) { 
                //
            }
     }
    

    in you Modal ViewController class create delegate

    var delegate: MyProtocol?
    

    create a protocol with the method name sendData in MyProtocol and in your presentingViewController where you are assigning the delegate, implement the MyProtocol method

    protocol MyProtocol: class {
        func sendData(typeState: String, categoryState: String)
    }
    
    class ViewController: UIViewController, MyProtocol {
        var typeState: String?
        var categoryState: String?
    
        func sendData(typeState: String, categoryState: String) {
           self.typeState = typeState
           self.categoryState = categoryState
        }
     }