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.
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.
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) }
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) }
The block to execute after the view controller is dismissed. This block has no return value and takes no parameters.
According to the View Controller Programming guide for iPhone OS, this is incorrect when it comes to dismissing modal view controllers you should use delegation. So before presenting your modal view make yourself the delegate and then call the delegate from the modal view controller to dismiss.
Passing Data Between View Controllers Using Segues (A → B) If you're using Storyboards, you can pass data between view controllers with segues, using the prepare(for:sender:) function. Passing data between view controllers, using Storyboards, isn't that much different from using XIBs.
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) }
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) } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With