SwiftUI 无法从 Class 方法更改颜色按钮
SwiftUI Can't Change Color Button from Class Method
我已经创建了一个 KetupatButton class,方法如下:
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)
}))
}
}
但是,当我从我的 ContentView 调用 class 并点击按钮时,按钮不会改变它的颜色。即使当我打印 colorToShow 变量时,它也发生了变化。但是按钮的 UI 颜色没有改变...
这是我的 ContentView
struct ContentView: View {
var button1 = KetupatButton()
var body: some View {
button1.createButton(size: 200)
}
}
您应该遵循更结构化的方法:将您的视图模型(即您的 class)与视图分开。以下是一些要遵循的步骤:
- 如果可以避免,您的视图模型不应包含该视图。创建一个特定的视图来显示按钮,与逻辑分开。您的按钮可能如下所示:
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)
}
}
}
- 您的视图模型应该是一个 Observable 对象。此外,触发 UI 变化的值应该是
@Published
变量。另外我还做了一个条件改变颜色自动改变的方法,这样就可以去掉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
应该创建一个视图模型的实例作为 @StateObject
与子视图共享,就像我们上面创建的 ButtonView
:
struct ContentView: View {
@StateObject var viewModel = KetupatButton()
var body: some View {
ButtonView(viewModel: viewModel, size: 200)
}
}
现在,您可以看到按钮的颜色发生了变化。
我已经创建了一个 KetupatButton class,方法如下:
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)
}))
}
}
但是,当我从我的 ContentView 调用 class 并点击按钮时,按钮不会改变它的颜色。即使当我打印 colorToShow 变量时,它也发生了变化。但是按钮的 UI 颜色没有改变...
这是我的 ContentView
struct ContentView: View {
var button1 = KetupatButton()
var body: some View {
button1.createButton(size: 200)
}
}
您应该遵循更结构化的方法:将您的视图模型(即您的 class)与视图分开。以下是一些要遵循的步骤:
- 如果可以避免,您的视图模型不应包含该视图。创建一个特定的视图来显示按钮,与逻辑分开。您的按钮可能如下所示:
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)
}
}
}
- 您的视图模型应该是一个 Observable 对象。此外,触发 UI 变化的值应该是
@Published
变量。另外我还做了一个条件改变颜色自动改变的方法,这样就可以去掉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
应该创建一个视图模型的实例作为@StateObject
与子视图共享,就像我们上面创建的ButtonView
:
struct ContentView: View {
@StateObject var viewModel = KetupatButton()
var body: some View {
ButtonView(viewModel: viewModel, size: 200)
}
}
现在,您可以看到按钮的颜色发生了变化。