Reputation: 538
Given this code:
import SwiftUI
struct ContentView: View {
@State private var someView = DefaultView()
var body: some View {
VStack { someView }
//.onAppear { someView.change() } //1. Color not changing from here, isDisplay remains false
}
}
struct DefaultView: View {
@State private var isDisplay = false
func change() {
isDisplay = true
print("isDisplay = \(self.isDisplay)")
}
var body: some View {
Text("Hello!")
.foregroundColor(isDisplay ? .red : .blue)
//.onAppear { change() } //2. Color and isDisplay property is changing from here well
}
}
I'd like to call change func from parent view (ContentView 1.). That runs because the print is visible on the debug area, but there is no any changes, the isDisplay property does not change from false to true. Why does this work that way? How can I change the @state property from the parent class?
Edit: It could work:
struct DefaultView: View {
public var isDisplay: Bool
init() {
isDisplay = false
}
mutating func change() {
isDisplay = true
print("isDisplay = \(self.isDisplay)")
}
var body: some View {
Text("Hello!")
.foregroundColor(isDisplay ? .red : .blue)
}
}
Upvotes: 2
Views: 2246
Reputation: 946
I would use @Binding
to change the value of the property in your DefaultView
from a parent view. Here is a brief example.
struct ContentView: View {
@State private var changeColor = false
var body: some View {
VStack {
Button {
changeColor.toggle()
} label: {
Text("Toggle Button")
.padding()
.foregroundColor(.red)
}
DefaultView(isDisplay: $changeColor)
}
}
}
struct DefaultView: View {
@Binding var isDisplay: Bool
var body: some View {
Text("Hello")
.foregroundColor(isDisplay ? .red : .blue)
}
}
Upvotes: 2
Reputation: 1
The way you showed your code in question is not the way SwiftUI works, you are thinking in UIKit and coding SwiftUI?
Once you fired a View there is no return to use the imbedded function or any thing! SwiftUI-View is more like a gun build you can not change the direction or other property of it, after render is done! in the other hand UIKit-View is more like Rocket, after firing you have control on it and you can change destination and more other things as well. So there is deference between them, make your build lighter as possible. Because your going firing lots and SwiftUI should handel them as much as easily as possible.
Here the right way:
struct ContentView: View {
@State private var isDisplay: Bool = Bool()
var body: some View {
DefaultView(isDisplay: isDisplay)
Button("update") { isDisplay.toggle() }.padding()
}
}
struct DefaultView: View {
let isDisplay: Bool
var body: some View {
Text("Hello!")
.foregroundColor(isDisplay ? .red : .blue)
}
}
Upvotes: 2