Reputation: 51
I navigated to a VC (lets call is VC A) from a presented VC. In VC A, I have a container view and it has a VC (lets call is VC B). From VC B I presented another VC (lets call is VC C). From VC C I need to pass a few data back to VC B. How can I achieve the same.
I tried using protocol, but protocol is not hitting my VC B.Its hitting VC A only. But since I'm presenting VC C from VC B, I can't connect the delegate to self from VC A. So it's not working.
Again tried to save the data a global variable. And I tried to set the value to fields in viewWillAppear and ViewDidAppear in VC B.But due to some reason it's crashing every time. The crash is getting on the line
containerView.addSubview(remitController.view).
let remitController = remitStoryboard.instantiateViewController(withIdentifier: "AddBeneficiaryController") as! AddBeneficiaryController
addChildViewController(remitController)
remitController.view.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(remitController.view)
NSLayoutConstraint.activate([
remitController.view.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
remitController.view.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
remitController.view.topAnchor.constraint(equalTo: containerView.topAnchor),
remitController.view.bottomAnchor.constraint(equalTo: containerView.bottomAnchor)
])
remitController.didMove(toParentViewController: self)
Upvotes: 0
Views: 707
Reputation: 1
I once encountered this problem when i tried using a container view for two view controllers depending on a flag. The solution i came up with was using delegates. I suggest you create a delegate to be implemented by VC B. At the point of instantiation of VC C you set the delegate. It should be declared as weak in VC C to avoid a retain cycle and memory leak. Call the delegate and send back your data from VC C back to B
protocol CtoBDelegate : class{
func sendMyDataBack()//pass in any arguments also
}
class VC_C : UIViewController{
weak var delegate : CtoBDelegate?
override func viewDidLoad(){
//do something
delegate?.sendMyDataBack
}
}
class VC_B : UIViewController{
override func viewDidLoad(){
let vc_C = //instantiate your view controller
vc_C.delegate = self
present(vc_C, animated : true)
}
}
extension class VC_B : CtoBDelegate{
func sendMyDataBack(){
//do something with received data in VC_B
}
}
Another crude way you could implement a communication is using NotificationsCenter. Simply register your notifications in VC_B and set up a method to be called when a notification is received. Then post a notification from VC_C passing along whatever you need with the userinfo of the notification. If you opt for this do remember to remove the notification observer from VC_B when you are done to avoid a leak.
Upvotes: 0
Reputation: 24341
Use closure
to solve the problem statement.
Create a closure
in VCC
controller,
class VCC: UIViewController {
var handler: ((String)->())?
func passDataToVCB() {
handler?("This is sample data.")
}
}
Call the handler
whenever you want to pass data back to VCB
along with the relevant data. I used String
here.
Next, in VCB
when you're presenting instance of VCC
, set the handler
value,
if let vcc = self.storyboard?.instantiateViewController(withIdentifier: "VCC") as? VCC {
vcc.handler = {(value) in
print(value)
}
//present vcc here...
self.present(vcc, animated: true, completion: nil)
}
Upvotes: 1