我有一个包含多个布尔变量的表单,可以在切换时更改图像,但是当我单击任何按钮时,所有变量都会更改图像?我已将它们全部拉入具有相同结果的单独子视图中。对我来说没有任何意义。任何帮助,将不胜感激。可能我忽略了一些简单的东西,但如果我能看到它,我会被诅咒。
这是代码。
@State var total: String = ""
@State var date: Date = Date()
@State var bathroom: Bool = false
@State var steps: Bool = false
@State var furniture: Bool = false
@State var travel: Bool = false
@State var woodFloor: Bool = false
@State var concreteFloor: Bool = false
@State var takeUp: Bool = false
var body: some View {
VStack {
Form {
Section(header: Text("Job Info")
.font(.title2)
.foregroundColor(.blue)
.fontWeight(.bold)
.padding(.bottom, 10)
) {
VStack(alignment: .leading) {
DatePicker("Date", selection: $date)
.font(.title3)
.foregroundColor(.black)
.padding(.bottom, 10)
HStack(alignment: .center) {
Text("Total: $")
.font(.title3)
.foregroundColor(.black)
.padding(.trailing, 0)
TextField("", text: $total)
.font(.title3)
.frame(width: 100, height: 20, alignment: .leading)
.background(Color.yellow)
.foregroundColor(.black)
.cornerRadius(5)
Spacer()
}
.padding(.bottom, 20)
}
Section(header: Text("Addons")
.font(.title3)
.foregroundColor(.blue)
.padding(.bottom, 10)
) {
VStack(alignment: .leading, spacing: 5) {
Spacer()
HStack {
Text("Bathroom")
Spacer()
Button {
self.bathroom.toggle()
} label: {
Image(systemName: bathroom ? "checkmark.square" : "square")
}
}
HStack {
Text("Steps")
Spacer()
Button {
self.steps.toggle()
} label: {
Image(systemName: steps ? "checkmark.square" : "square")
}
}
HStack {
Text("Furniture")
Spacer()
Button {
self.furniture.toggle()
} label: {
Image(systemName: furniture ? "checkmark.square" : "square")
}
}
Spacer()
}
}
}
}
答案 0 :(得分:1)
您将所有按钮放在一行中(VStack
和 HStacks
创建一个视图,因此为一行),并且 Form
(作为 List
)在任何时候发送所有操作在一行中单击任何按钮(它被设计为在一行中有一个活动元素)。
所以解决方案要么是删除 VStack
Section(header: Text("Addons")
.font(.title3)
.foregroundColor(.blue)
.padding(.bottom, 10)
) {
VStack(alignment: .leading, spacing: 5) { // << this !!
Spacer()
并让每个带有按钮的 HStack
位于自己的行中...
... 或者使用带有点击手势的 Image
代替按钮,例如
HStack {
Text("Steps")
Spacer()
Image(systemName: steps ? "checkmark.square" : "square")
.padding()
.onTapGesture {
self.steps.toggle()
}
}
答案 1 :(得分:0)
如果您在 Section
的 Form
中有一个按钮,则整个部分将充当按钮。因此,当您点击它时,所有 3 个按钮操作都会执行。
相反,您可以将 Image
与 .onTapGesture{}
修饰符一起使用。这样,你就会得到你想要的。
示例代码,
Image(systemName: bathroom ? "checkmark.square" : "square")
.foregroundColor(.blue)
.onTapGesture {
self.bathroom.toggle()
}
答案 2 :(得分:0)
我认为您对 Form
的期望是错误的。 Form
不要用花哨的东西制作灵活的列表。如果您希望能够做任何您想做的事情并能够随意自定义您的列表,您可能应该使用 Grid
和其他普通组件,例如 VStack
...
在不解决这些限制的情况下,查看您可以使用 Form
做什么或不可以做什么的最简单方法是转到 iPhone 上的设置,查看设置的不同部分是如何进行的。您可以非常轻松地实现几乎所有这些目标,无需太多工作。但是,如果您想要一些与您在设置中看到的有所不同的东西,那么您可能需要一种解决方法来在您的应用中实现它,因为 Form
不灵活。
从设置中获取的 Form
可以做什么的示例:
为了澄清起见,我并不是说您无法使用表单实现您想要的目标。我的意思是,试图强迫表单成为它们不应该成为的东西,这很可能不是一个好主意。
那你现在该怎么办?您可能应该用 Toggle
替换您的按钮,以便获得与您在设置中看到的类似的内容。
[其他人已经说过如何解决您当前的问题,所以我只说更好的方法]
考虑使用这样的东西:
struct ContentView: View {
@State var date = Date()
@State var total = ""
@State var bathroom = false
@State var steps = false
@State var furniture = false
var body: some View {
NavigationView { // DELETE this if the view before this view
// already has a navigation view
Form {
Section(header: Text("Job Info")) {
DatePicker("Date", selection: $date)
NavigationLink.init(
destination: FormTextFieldView(name: "Total $", value: $total),
label: {
Text("Total")
Spacer()
Text("$ " + total).foregroundColor(.secondary)
})
}
Section(header: Text("Addons")) {
Toggle("Bathroom", isOn: $bathroom)
Toggle("Steps", isOn: $steps)
Toggle("Furniture", isOn: $furniture)
}
}
.navigationBarTitle("Form", displayMode: .inline)
}
}
}
struct FormTextFieldView: View {
let name: String
@Binding var value: String
var body: some View {
Form {
TextField(name, text: $value)
}
.navigationBarTitle(name)
}
}
首先,因为它是在毫不费力的情况下构建的。您几乎不需要使用任何修饰符。这么简单!
其次,这将适用于任何苹果设备。当您使用修饰符时,特别是为视图设置框架时,您需要考虑如果使用例如一个 iPad。当您使用这种方法时,您无需担心这一点。