简体   繁体   中英

How to get variable value of child view in parent view on SwiftUI?

I have one view "CancelRow"

struct CancelRow: View {
    @Binding var isSelected: Bool

    init(isSelected: Binding<Bool>) {
        self._isSelected = isSelected //just to get bool value
    }

   @ViewBuilder var body: some View {
    HStack {
       Text(verbatim: "Hello, \(isSelected)")
    }
}

I have another view i which i want to show button active or not based on "isSelected" from "CancelRow"

// AnotherVIew

CancelRow(isSelected: .constant(false))
    Spacer()
    SubmitButtonView(buttonTitle: title, buttonCallBack: {
        goToOtherScreen()
    }, isActive: isSelected ) // how to access this variable from  "CancelRow"

As mentioned in the comments, state should be owned by a parent view and then passed to the child views.

In your case, you don't actually need to use a custom initializer for CancelRow in the example you gave (you could rely on just the synthesized initializer), but as request, this uses an initializer.

struct CancelRow: View {
    @Binding var isSelected: Bool
    
    init(isSelected: Binding<Bool>) {
        self._isSelected = isSelected
    }
    
    @ViewBuilder var body: some View {
        HStack {
            Text(verbatim: "Hello, \(isSelected)")
        }
    }
}

struct SubmitButtonView : View {
    var buttonTitle : String
    var buttonCallBack : () -> Void
    var isActive : Bool
    
    var body: some View {
        Text("Submit: \(isActive ? "true" : "false")")
    }
}

struct ContentView: View {
    @State private var isSelected = false
    
    var title : String {
        "Title"
    }
    
    var body: some View {
        VStack {
            Button("Toggle") {
                isSelected.toggle()
            }
            CancelRow(isSelected: $isSelected)
            SubmitButtonView(buttonTitle: title, buttonCallBack: {
                goToOtherScreen()
            }, isActive: isSelected )
        }
    }
    
    func goToOtherScreen() {
        print("Navigate")
    }
}

There is this concept of Source of truth . In oversimplified terms, you need to have a @State private var in one of your structs. If that @State private var holds any information some other struct would like to use, the second struct should have @Binding var and be initialised from the first struct with the value of @State private var .

In code below struct AnotherView is the source of truth, it has @State private var , and other structs have @Binding and are initialised with value of that @State private var .

struct AnotherView:

 @State private var isSelected = false var body: some View { VStack { CancelRow(isSelected: $isSelected) Spacer() SubmitButtonView(isSelected: $isSelected) } }

struct CancelRow:

 @Binding var isSelected: Bool var body: some View { Text(isSelected? "I'm selected": "I'm not selected") }

struct SubmitButtonView:

 @Binding var isSelected: Bool var body: some View { Button { // do something on tap } label: { Text("Button text") } }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM