ViewController Pushing Swift From One VC to Another VC And Returning back - ios

Consider two view controller Controller1 and Controller2, I have created a form of many UITextField in controller 1, in that when a user clicks a particular UITextField it moves to Controller2 and he selects the data there.
After selecting the data in Controller2 it automatically moves to Controller1, while returning from controller2 to controller1 other UITextfield data got cleared and only the selected data from controller2 is found. I need all the data to be found in the UITextfield after selecting.
Here is the code for returning from Controller2 to Controller1
if(Constants.SelectedComplexName != nil)
{
let storyBoard: UIStoryboard = UIStoryboard(name: "NewUserLogin", bundle: nil)
let newViewController = storyBoard.instantiateViewController(withIdentifier: "NewUser") as! NewUserRegistrationViewController
self.present(newViewController, animated: true, completion: nil)
}

To pass messages you need to implement Delegate.
protocol SecondViewControllerDelegate: NSObjectProtocol {
func didUpdateData(controller: SecondViewController, data: YourDataModel)
}
//This is your Data Model and suppose it contain 'name', 'email', 'phoneNumber'
class YourDataModel: NSObject {
var name: String? //
var phoneNumber: String?
var email: String?
}
class FirstViewController: UIViewController, SecondViewControllerDelegate {
var data: YourDataModel?
var nameTextField: UITextField?
var phoneNumberTextField: UITextField?
var emailTextField: UITextField?
override func viewDidLoad() {
super.viewDidLoad()
callWebApi()
}
func callWebApi() {
//After Success Fully Getting Data From Api
//Set this data to your global object and then call setDataToTextField()
//self.data = apiResponseData
self.setDataToTextField()
}
func setDataToTextField() {
self.nameTextField?.text = data?.name
self.phoneNumberTextField?.text = data?.phoneNumber
self.emailTextField?.text = data?.email
}
func openNextScreen() {
let vc2 = SecondViewController()//Or initialize it from storyboard.instantiate method
vc2.delegate = self//tell second vc to call didUpdateData of this class.
self.navigationController?.pushViewController(vc2, animated: true)
}
//This didUpdateData method will call automatically from second view controller when the data is change
func didUpdateData(controller: SecondViewController, data: YourDataModel) {
}
}
class SecondViewController: UIViewController {
var delegate: SecondViewControllerDelegate?
func setThisData(d: YourDataModel) {
self.navigationController?.popViewController(animated: true)
//Right After Going Back tell your previous screen that data is updated.
//To do this you need to call didUpdate method from the delegate object.
if let del = self.delegate {
del.didUpdateData(controller: self, data: d)
}
}
}

push your view controller instead of a present like this
if(Constants.SelectedComplexName != nil)
{
let storyBoard: UIStoryboard = UIStoryboard(name: "NewUserLogin", bundle: nil)
let newViewController = storyBoard.instantiateViewController(withIdentifier: "NewUser") as! NewUserRegistrationViewController
self.navigationController?.pushViewController(newViewController, animated: true)
}
and then pop after selecting your data from vc2 like this
self.navigationController?.popViewController(animated: true)
and if you are not using navigation controller then you can simply call Dismiss method
self.dismiss(animated: true) {
print("updaae your data")
}

There are a few ways to do it, but it usually depends on how you move from VC#1 to VC#2 and back.
(1) The code you posted implies you have a Storyboard with both view controllers. In this case create a segue from VC#1 to VC#2 and an "unwind" segue back. Both are fairly easy to do. The link provided in the comments does a good job of showing you, but, depending on (1) how much data you wish to pass back to VC#1 and (2) if you wish to execute a function on VC#2, you could also do this:
VC#1:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "ShowVC2" {
if let vc = segue.destination as? VC2ViewController {
vc.VC1 = self
}
}
}
VC#2:
weak var VC1:VC1ViewController!
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if isMovingFromParentViewController {
VC1.executeSomeFunction()
}
}
Basically you are passing the entire instance of VC1 and therefore have access to everything that isn't marked private.
(2) If you are presenting/dismissing VC#2 from VC#1, use the delegate style as described by one of the answers.
VC#1:
var VC2 = VC2ViewController()
extension VC1ViewController: VC2ControlllerDelegate {
func showVC2() {
VC2.delegate = self
VC2.someData = someData
present(VC2, animated: true, completion: nil)
}
function somethingChanged(sender: VC2ViewController) {
// you'll find your data in sender.someData, do what you need
}
}
VC#2:
protocol VC2Delegate {
func somethingChanged(sender: VC2ViewController) {
delegate.somethingChanged(sender: self)
}
}
class DefineViewController: UIViewController {
var delegate:DefineVCDelegate! = nil
var someData:Any!
func dismissMe() {
delegate.somethingChanged(sender: self)
dismiss(animated: true, completion: nil)
}
}
}
Basically, you are making VC#1 be a delegate to VC2. I prefer the declaration syntax in VC#2 for `delegate because if you forget to set VC#1 to be a delegate for VC#2, you test will force an error at runtime.

Related

Calling Barcodescanner from another class, cant retrieve the data? [duplicate]

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)
}
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 using a navigation controller you will have to first grab the UINavigation Controller and then get the correct ViewController from the Navigation Controller stack.
Here's how my code looked in that case.
#IBAction func dismissViewController(_ sender: UIBarButtonItem) {
if let navController = presentingViewController as? UINavigationController {
let presenter = navController.topViewController as! OOTDListViewController
presenter.testValue = "Test"
}
dismiss(animated: true, completion: nil)
}
I am using the a tab bar so the working code is as below:
if let tabBar = self.presentingViewController as? UITabBarController {
let homeNavigationViewController = tabBar.viewControllers![0] as? UINavigationController
let homeViewController = homeNavigationViewController?.topViewController as! HomeController
homeViewController._transferedLocationID = self.editingLocationID!
}
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
weak 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: AnyObject {
func sendData(typeState: String, categoryState: String)
}
class ViewController: UIViewController, MyProtocol {
var typeState: String?
var categoryState: String?
override func viewDidApear() {
super.viewDidApear()
presentNewModalVC()
}
func presentNewModalVC() {
let modalVC = NewModalViewControllerToBePresented()
modalVC.delegate = self
present(modalVC, animated: true)
}
func sendData(typeState: String, categoryState: String) {
self.typeState = typeState
self.categoryState = categoryState
}
}

use popToRootViewController and pass Data

I'm applying for a junior developer position and I've got a very specific task, that already took me 3 days to complete. Sounds easy - pass data to rootViewController.
That's what I've done:
1)
private func userDefaultsToRootController() {
let input = textField.text!
defaults.set(input, forKey: "SavedLabel")
navigationController?.popViewController(animated: true)
}
private func segueToRootViewController() {
let destinationVC = MainScreen1()
let input = textField.text!
if input == "" { self.navigationController?.popToRootViewController(animated: true) }
destinationVC.input = input
navigationController?.pushViewController(destinationVC, animated: true)
}
private func popToNavigationController() {
let input = textField.text!
if let rootVC = navigationController?.viewControllers.first as? MainScreen1 {
rootVC.input = input
}
navigationController?.popToRootViewController(animated: true)
}
I've used CoreData
But here is the difficult part - I've got an email, that all these methods are not good enough and I need to use delegate and closure. I've done delegation and closures before, but when I popToRootViewController delegate method passes nil. Could you at least point where to find info about this?
** ADDED **
There are 2 View Controllers: Initial and Second one.
That's what I have in the Initial View Controller:
var secondVC = MainScreen2()
override func viewDidLoad() {
super.viewDidLoad()
secondVC.delegate = self
}
That's how I push SecondViewController
#objc private func buttonTapped(_ sender: CustomButton) {
let nextViewController = MainScreen2()
navigationController?.pushViewController(nextViewController, animated: true)
}
In SecondViewController I've got this protocol
protocol PassData {
func transferData(text: String)
}
Also a delegate:
var delegate: PassData?
This is how I go back to initial view controller
#objc private func buttonTapped(_ sender: CustomButton) {
if let input = textField.text {
print(input)
self.delegate?.transferData(text: input)
self.navigationController?.popToRootViewController(animated: true)
}
}
Back to the Initial view controller where I've implemented delegate method
extension MainScreen1: PassData {
func transferData(text: String) {
print("delegate called")
label.text = text
}
}
Delegate doesn't get called.
BASED ON YOUR EDIT:
You must set the delegate in buttonTapped
#objc private func buttonTapped(_ sender: CustomButton) {
let nextViewController = MainScreen2()
nextViewController.delegate = self // HERE WHERE YOU SET THE DELEGATE
navigationController?.pushViewController(nextViewController, animated: true)
}
You can delete the second instance and your code in viewDidLoad. That's not the instance you push.
This should point you in the right direction to use delegation and completion handler.
protocol YourDelegateName {
func passData(data:YourDataType)
}
class SecondViewController: UIViewController {
var delegate: YourDelegateName?
func passDataFromSecondViewController(){
YourCoreDataClass.shared.getCoreData { (yourStringsArray) in
self.delegate?.passData(data: yourStringsArray)
self.navigationController?.popToRootViewController(animated: true)
}
}
class InitialViewController: UIViewController, YourDelegateName {
override func viewDidLoad() {
super.viewDidLoad()
// or whenever you instantiate your SecondViewController
let secondViewController = SecondViewController()
secondViewController.delegate = self //VERY IMPORTANT, MANY MISS THIS
self.navigationController?.pushViewController(createVC, animated: true)
}
func passData(data:YourDataType){
//user your data
}
}
class YourCoreDataClass: NSObject {
static let shared = YourCoreDataClass()
func getCoreData (completion: ([String]) -> ()){
........... your code
let yourStringsArray = [String]() // let's use as example an array of strings
//when you got the data your want to pass
completion(yourStringsArray)
}
}

How can I wait until a view controller is done presenting and dismissed to run next line of code? [duplicate]

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)
}
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 using a navigation controller you will have to first grab the UINavigation Controller and then get the correct ViewController from the Navigation Controller stack.
Here's how my code looked in that case.
#IBAction func dismissViewController(_ sender: UIBarButtonItem) {
if let navController = presentingViewController as? UINavigationController {
let presenter = navController.topViewController as! OOTDListViewController
presenter.testValue = "Test"
}
dismiss(animated: true, completion: nil)
}
I am using the a tab bar so the working code is as below:
if let tabBar = self.presentingViewController as? UITabBarController {
let homeNavigationViewController = tabBar.viewControllers![0] as? UINavigationController
let homeViewController = homeNavigationViewController?.topViewController as! HomeController
homeViewController._transferedLocationID = self.editingLocationID!
}
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
weak 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: AnyObject {
func sendData(typeState: String, categoryState: String)
}
class ViewController: UIViewController, MyProtocol {
var typeState: String?
var categoryState: String?
override func viewDidApear() {
super.viewDidApear()
presentNewModalVC()
}
func presentNewModalVC() {
let modalVC = NewModalViewControllerToBePresented()
modalVC.delegate = self
present(modalVC, animated: true)
}
func sendData(typeState: String, categoryState: String) {
self.typeState = typeState
self.categoryState = categoryState
}
}

How to pass data to another controller on dismiss ViewController?

I want to pass my data from one ViewController to another VC on VC dismiss. Is it possible?
I've tried the next method and no success:
On button click:
self.dismiss(animated: true) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "EditViewController") as! EditViewController
controller.segueArray = [values]
}
when EditViewController appears again, my segueArray is nil there.
How can I pass my data from my ViewController to the EditViewController on dismiss?
The best way to pass data back to the previous view controller is through delegates... when going from ViewController A to B, pass view controller A as a delegate and on the viewWillDisappear method for ViewController B, call the delegate method in ViewController A.. Protocols would help define the delegate and the required methods to be implemented by previous VC. Here's a quick example:
Protocol for passing data:
protocol isAbleToReceiveData {
func pass(data: String) //data: string is an example parameter
}
Viewcontroller A:
class viewControllerA: UIViewController, isAbleToReceiveData {
func pass(data: String) { //conforms to protocol
// implement your own implementation
}
prepare(for: Segue) {
/** code for passing data **/
let vc2 = ViewCOntrollerB() /
vc2.delegate = self //sets the delegate in the new viewcontroller
//before displaying
present(vc2)
}
}
Dismissing viewcontroller:
class viewControllerB: UIViewController {
var delegate: isAbleToReceiveData
viewWillDisappear {
delegate.pass(data: "someData") //call the func in the previous vc
}
}
In the dismiss completion block, you create a new instance of the EditViewController. I assume that another EditViewController instance exists back in the navigation stack, you need to find that instance & set the segueArray to values.
That you can achieve by iterating through your navigation stack's viewcontrollers like:
viewController.navigationController?.viewControllers.forEach({ (vc) in
if let editVC = vc as? EditViewController {
editVC.segueArray = ....
}
})
But I would recommend to use the delegate pattern, like:
protocol EditViewControllerDelegate: class {
func setSegueArray(segues: [UIStoryboardSegue])
}
In the viewcontroller (call it just ViewController) where the dismiss block is, declare a delegate property:
class ViewController: UIViewController {
weak var delegate: EditViewControllerDelegate?
....
}
Then on presenting the instance of (I assume from EditViewController) ViewController set the delegate like:
...
if let vc = presentingViewController as? ViewController {
vc.delegate = self
}
And conform the EditViewController to the delegate protocol like:
extension EditViewController: EditViewControllerDelegate {
func setSegueArray(segues: [UIStoryboardSegue]) {
// Do the data setting here eg. self.segues = segues
}
}
To detect when the back button is pressed on a view controller, I just use:
override func didMove(toParentViewController parent: UIViewController?) {
guard parent == nil else { return } // Back button pressed
... // Pass on the info as shown in you example
} // didMoveToParentViewController
A generic solution: (🔸 Swift 5.1 )
/**
* Returns a ViewController of a class Kind
* ## Examples:
* UIView.vc(vcKind: CustomViewController.self) // ref to an instance of CustomViewController
*/
public static func vc<T: UIViewController>(vcKind: T.Type? = nil) -> T? {
guard let appDelegate = UIApplication.shared.delegate, let window = appDelegate.window else { return nil }
if let vc = window?.rootViewController as? T {
return vc
} else if let vc = window?.rootViewController?.presentedViewController as? T {
return vc
} else if let vc = window?.rootViewController?.children {
return vc.lazy.compactMap { $0 as? T }.first
}
return nil
}

Passing a String/Object value to another ViewController

I am opening another ViewController using this:
let mainStoryboard: UIStoryboard = UIStoryboard(name:"Main", bundle:nil)
let homeViewController: UIViewController = mainStoryboard.instantiateViewController(withIdentifier: "IssueViewController")
self.present(homeViewController, animated: true, completion: nil)
Along with this, I need to pass a Person object and a String value to the 2nd ViewController.
struct Person {
var Name: String
var Details: String
}
What changes do I need to do to attach a Person object to my existing code?
EDIT: This is the 2nd ViewController
I am trying to retrieve the values from this view
class IssueViewController: UIViewController {
var person: Person = Person();
override func viewDidLoad() {
super.viewDidLoad()
}
}
//changes in first controller
let mainStoryboard: UIStoryboard = UIStoryboard(name:"Main",bundle:Bundle.main)
let homeViewController: IssueViewController = mainStoryboard.instantiateViewController(withIdentifier: "IssueViewController") as! IssueViewController
homeViewController.person = Person(Name:"ABC",Details:"XYZ")
homeViewController.bindWithData(yourStringObject)
self.present(homeViewController, animated: true, completion: nil)
//changes in second view controller
class IssueViewController: UIViewController {
var person: Person = Person(Name:"",Details:"");
override func viewDidLoad() {
super.viewDidLoad()
print(person.Name)
print(person.Details)
}
func bindWithData(yourStringObject:String){
//your code here.
}
}

Resources