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"
CodePudding user response:
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")
}
}
CodePudding user response:
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") } }