Frederick C. Lee
Frederick C. Lee

Reputation: 9503

Sharing common variables within a Container View

Scenario:
I had a large view that I want to break up into a container view having couple of child views.
So each view has its own .string file. The paradigm: dissemination of processes from one file to the children as a 'collective'.

The container view would act as the hub, the intelligence.

I don't want this to be overly complicated; merely modularizing the logic in discrete parts for easy maintenance.

Problem: I can only go one-way @State ---> @Binding between struct Views without going thru a Class Object.
Is there a way to return values; e.g., two-way data exchange?
That is, child views sharing their common views with the parent/container?

 View1  |  View2          &   View2     |   View1 <br/>
@State -->@Binding (data) & @Binding <-- @State (result)?

I must I use some sort of singleton class object for the data exchange?

Again, I'm for simplicity of design vs a large single struct View.

Upvotes: 0

Views: 125

Answers (1)

New Dev
New Dev

Reputation: 49590

Binding is the way a value is "returned" from a child to parent. If the child didn't update the value (i.e. just one-way parent -> child, then you wouldn't need a binding - just pass the variable in an init).

struct Child: View {
   @Binding var num: Int
   var body: some View {
      VStack {
         Text("\(num)")
         Button("increase") { self.num += 1 }
      }
   }
}

struct Parent: View {
   @State var sharedNum: Int = 0
   var body: some View {
      VStack {
         Text("\(sharedNum)")
         Child(num: $sharedNum)
         Child(num: $sharedNum)
      }
      .onChange(of: sharedNum) { print("shared num", $0) } // iOS14 required
   }
}

Both children and the parent would display the same number regardless of which of the children changed it.


But, sometimes a child might need to notify the parent not necessarily through a value change. Then you could use a callback:

struct Child: View {
   var onClick: (Int) -> Void

   var body: some View {
      Button("generate random") { 
         onClick(Int.random(1...100))
      }
   }
}

struct Parent: View {
   var body: some View {
      Child {
         print("new random", $0)
      }
   }
}

Upvotes: 1

Related Questions