How to pass data to parent view controller
One strategy would be to set the parent as a delegate of the child. You would create this relationship in a prepare(for:sender:)
function.
If you are unfamiliar with delegation, this article is a good guide: https://medium.com/@jamesrochabrun/implementing-delegates-in-swift-step-by-step-d3211cbac3ef
How to pass data from child to parent view controller? in swift
You can use protocols/delegate
Here is a very very straightforward explanation, no bs:
https://www.youtube.com/watch?v=guSYMPaXLaw
Or in your situation you can also use NSNotificationCenter
You can do something like this:
The "sender" view controller would do
let nc = NSNotificationCenter.defaultCenter()
nc.postNotificationName("printValue", object: nil, userInfo: ["value" : "Pass Me this string"])
The receiver view controller then can listen to the notification.
let nc = NSNotificationCenter.defaultCenter()
nc.addObserver(self, selector: #selector(printValue), name: "printValue", object: nil)
func printValue(notification:NSNotification) {
let userInfo:Dictionary<String,String> = notification.userInfo as! Dictionary<String,String>
let item = userInfo["value"]! as String
print(item,self)
}
Swift - Pass data from Child View to Parent View
So as per the code you have done with declaration but not initialized the delegate. So go to you ParentView and assign the delegate in viewDidLoad or in the function where you prepare to move on child like:-
toChildView.delegate = self
And try again. :-)
How to pass data from parent view controller to child container view controller
You can try it more early like
let childVC = storyboard!.instantiateViewController(withIdentifier: "ChildVC") as! ChildVC
childVC.boolVariable = true
Swift - Pass data from parent view controller to child view controller
When you add a Container View
in storyboard it adds a child view controller and a segue from the parent view controller to child view controller.
This segue is performed immediately after the parent view controller is loaded. Pass the data from EventDetails
to InvitedController
in prepare for segue
method
class EventsMainController: UIViewController {
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "EventDetails" {
if let eventDetails = segue.destination as? EventDetails {
eventDetails.eventId = "FromEventsMainController"
}
}
}
}
class EventDetails: UIViewController {
var eventId = String()
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "InvitedController" {
if let invitedController = segue.destination as? InvitedController {
invitedController.eventId = self.eventId
}
}
}
}
class InvitedController: UIViewController {
var eventId = String()
override func viewDidLoad() {
super.viewDidLoad()
print(eventId)//FromEventsMainController
}
}
how to pass data to previous viewController in iOS swift?
you can use delegate like what @Aqua said. or use observation for this.
class ParentViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(self.updateParentViewController(_:)), name: Notification.Name(rawValue: "updateParentViewController"), object: nil)
}
@IBaction func updateParentViewController(_ notification: NSNotification){
if let receivedData = notification.userInfo?["data"] as? Any {
//use received data
// update your parentViewController.
}
}
}
//.............
class ChildViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
func sendDataToParentViewController() {
let dataDict:[String: Any] = ["data"://what you want to send.]
NotificationCenter.default.post(name: . updateParentViewController, object: nil, userInfo: dataDict)
}
}
this works for me.
How do I pass data from a child view to a parent view to another child view in SwiftUI?
You can use EnvironmentObject for stuff like this...
The nice thing about EnvironmentObject is that whenever and wherever you change one of it's variables, it will always make sure that every where that variable is used, it's updated.
Note: To get every variable to update, you have to make sure that you pass through the BindableObject class / EnvironmentObject on everyView you wish to have it updated in...
SourceRectBindings:
class SourceRectBindings: BindableObject {
/* PROTOCOL PROPERTIES */
var willChange = PassthroughSubject<Application, Never>()
/* Seems Like you missed the 'self' (send(self)) */
var sourceRect: CGRect = .zero { willSet { willChange.send(self) }
}
Parent:
struct ParentView: view {
@EnvironmentObject var sourceRectBindings: SourceRectBindings
var body: some View {
childViewA()
.environmentObject(sourceRectBindings)
childViewB()
.environmentObject(sourceRectBindings)
}
}
ChildViewA:
struct ChildViewA: view {
@EnvironmentObject var sourceRectBindings: SourceRectBindings
var body: some View {
// Update your frame and the environment...
// ...will update the variable everywhere it was used
self.sourceRectBindings.sourceRect = CGRect(x: 0, y: 0, width: 300, height: 400)
return Text("From ChildViewA : \(self.sourceRectBindings.sourceRect)")
}
}
ChildViewB:
struct ChildViewB: view {
@EnvironmentObject var sourceRectBindings: SourceRectBindings
var body: some View {
// This variable will always be up to date
return Text("From ChildViewB : \(self.sourceRectBindings.sourceRect)")
}
}
LAST STEPS TO MAKE IT WORK
• Go into your highest view you want the variable to update which is your parent view but i usually prefer my SceneDelegate ... so this is how i usually do it:
let sourceRectBindings = SourceRectBindings()
• Then in the same class 'SceneDelegate' is go to where i specify my root view and pass through my EnviromentObject
window.rootViewController = UIHostingController(
rootView: ContentView()
.environmentObject(sourceRectBindings)
)
• Then for the last step, I pass it through to may Parent view
struct ContentView : View {
@EnvironmentObject var sourceRectBindings: SourceRectBindings
var body: some View {
ParentView()
.environmentObject(sourceRectBindings)
}
}
If you run the code just like this, you'll see that your preview throws errors. Thats because it didn't get passed the environment variable.
To do so just start a dummy like instance of your environment:
#if DEBUG
struct ContentView_Previews : PreviewProvider {
static var previews: some View {
ContentView()
.environmentObject(SourceRectBindings())
}
}
#endif
Now you can use that variable how ever you like and if you want to pass anything else other that the rect ... you can just add the variable to the EnvironmentObject class and you can access and update it
Swift sending data from child view to parent view controller
Delegation pattern is your friend.
Declare a protocol on your child view controller that the parent view controller will implement. Whenever you want, call a method on the delegate reference you are holding in the child view controller - this will update the parent view controller with data from child VC.
This SO question explains the child parent delegation neatly How do I set up a simple delegate to communicate between two view controllers?
Related Topics
How Detect Swipe Gesture Direction
Create Singleton of a Viewcontroller in Swift 3
Ios: One Ibaction for Multiple Buttons
How to Deserialize an Escaped JSON String with Nsjsonserialization
Passing Variables Between View Controllers
Differentiate Between Screen Lock and Home Button Press on iOS7
Is There a Simple Way to Edit/Modify a Uilocalnotification
New Itunes Connect Interface -- Should It Immediately Be Seen on "Prerelease"
Uicellview Cell Layout in Swift
Add Cocoapods to Tests Target Too
An Elegant Way to Ignore Any Errors Thrown by a Method
Apple Push Notification Limitation
Corebluetooth: What Is the Lifetime of Unique Uuids
How to Use Http Live Streaming Protocol in iPhone Sdk 3.0
How to Pass Data from Child to Parent View Controller? in Swift
Flutter on iOS: Fatal Error: Module 'Cloud_Firestore' Not Found