Reputation: 453
i've created a KetupatButton class with 2 method like this:
class KetupatButton {
var condition = false
@State var colorToShow = Color(UIColor(red: 183/255, green: 191/255, blue: 150/255, alpha: 100))
func colorChange() {
if condition == false {
colorToShow = Color(UIColor(red: 183/255, green: 191/255, blue: 150/255, alpha: 100))
} else {
colorToShow = Color(UIColor(red: 19/255, green: 58/255, blue: 27/255, alpha: 100))
}
}
func createButton(size: CGFloat) -> some View {
return AnyView(Button(action: {
self.condition = !self.condition
self.colorChange()
print(self.colorToShow)
print(self.condition)
}, label: {
Rectangle()
.frame(width: size, height: size, alignment: .leading)
.foregroundColor(colorToShow)
}))
}
}
But, when I call that class from my ContentView and tap the button, the button don't change it's color. Even though when i print the colorToShow variable, it changed. But the UI color of the button didn't change...
Here is my ContentView
struct ContentView: View {
var button1 = KetupatButton()
var body: some View {
button1.createButton(size: 200)
}
}
Upvotes: 0
Views: 55
Reputation: 4006
You should follow a more structured approach: separate your view model, which is your class, from the views. Here are some steps to follow:
struct ButtonView: View {
// Receive the view model
@ObservedObject var viewModel: KetupatButton
let size: CGFloat
var body: some View {
Button {
// Use this to animate the change
withAnimation {
// The condition will automatically change the color, see the view model code
viewModel.condition.toggle()
}
} label: {
Rectangle()
.frame(width: size, height: size, alignment: .leading)
.foregroundColor(viewModel.colorToShow)
}
}
}
@Published
variables. In addition, I also made in a way that the color changes automatically when the condition changes, so you can get rid of colorChnage()
.class KetupatButton: ObservableObject {
// When this variable changes, it will change also the color.
var condition = false {
didSet {
if condition {
colorToShow = Color(UIColor(red: 19/255, green: 58/255, blue: 27/255, alpha: 100))
} else {
colorToShow = Color(UIColor(red: 183/255, green: 191/255, blue: 150/255, alpha: 100))
}
}
}
@Published var colorToShow = Color(UIColor(red: 183/255, green: 191/255, blue: 150/255, alpha: 100))
}
ContentView
should create an instance of the view model as a @StateObject
to share with subviews, like ButtonView
that we created above:struct ContentView: View {
@StateObject var viewModel = KetupatButton()
var body: some View {
ButtonView(viewModel: viewModel, size: 200)
}
}
Now, you can see that the color of the button changes.
Upvotes: 1