SwiftUI 单击列表中的一行,将该列表中的每一行设置为 true
SwiftUI Clicking on one Row in a List, sets every row on that list to true
我有一个看起来像这样的列表:
但是当我点击一行时,每一行中的每个圆圈都会得到 activated/deactivated。我现在在这个问题上坐了几个小时,不知道该怎么做。谁能帮帮我?
我认为问题与 DispatchQueue.main.async
行有关。但是如果我在代码中不使用DispatchQueue.main.async
,列表是空的,无法填充。如果我不这样做 DispatchQueue.main.async
,我会收到两次以下错误:
Modifying state during view update, this will cause undefined behavior.
所以如果我使用 DispatchQueue.main.async
列表可以被填充并且不是空的。但正如我之前所述,新问题是,当我单击一行时,列表中的每个圆(来自所有行)都会得到 activated/deactivated.
这是我的代码:
struct zettelDetailView: View {
var info: CreateInfo
@State var isChecked: Bool = false
func toggle(){
isChecked = !isChecked
}
@State var listItems = [CreateZettelDetailViewText]()
@State var executeThisAsyncThing: Bool = true
private func changeInfoListToArray() {
//String ist folgendermaßen aufgebaut:
//"Text/-t;" t = true; f = false "/-" und ";" sind splitter
// var returnArray = [CreateZettelDetailViewText]()
// let infoStr = info.list
let infoStr = "Das-t;Ist-f;Ein-f;Test-t;"
let infoArr1 = infoStr.split(separator: ";")
var infoArr2 = [[String]]()
print(infoArr1.count)
if infoArr1.count != 0 {
for i in 0...(infoArr1.count - 1) {
let x = infoArr1[i]
let y = x.split(separator: "-")[0] //text
let z = x.split(separator: "-")[1] //bool
var arr2 = [String]()
arr2.append(String(y))
arr2.append(String(z))
var zBool: Bool = false
if z == "t" {
zBool = true
} else if z == "f" {
zBool = false
}
infoArr2.append(arr2)
self.listItems.append(CreateZettelDetailViewText(text: "\(String(y))", isDone: zBool))
}
}
executeThisAsyncThing = false
}
var body: some View {
// listItems = changeInfoListToArray()
DispatchQueue.main.async {
if self.executeThisAsyncThing {
self.changeInfoListToArray()
}
}
return VStack {
VStack {
Text(info.name)
.font(.largeTitle)
Text("\(info.day) - \(info.time)")
}.offset(y: -50)
List(listItems) { a in
Button(action: self.toggle
// {
//
// if a.isDone {
// self.isChecked = true
// } else if !a.isDone {
// self.isChecked = false
// }
//
// print()
// print(a.id)
// print(a.text)
// print(a.isDone)
// print()
//
// }
){
HStack {
Image(systemName: self.isChecked ? "checkmark.circle.fill" : "circle")
Text(a.text)
}
}.onAppear() {
self.isChecked = true
}
}.offset(y: -50)
Button(action: addRow) {
Image(systemName: "plus.app.fill")
.offset(y: -20)
.font(.largeTitle)
}
}
}
private func addRow() {
// var arr = [[String]]()
// arr = getZettelData()
// arr.append(["ZettelName", "\(time)", "\(day)"])
//
// let defaults = UserDefaults.standard
// defaults.set(arr, forKey: "SavedZettelArray")
}
}
整个列表只有一个 isChecked
。每一行都使用相同的变量,因此当其中一个被点击时,所有的变量都会改变。
根据代码,列表中的每一项似乎都有一个 isDone
成员。尝试将图像名称的 self.isChecked
替换为 a.isDone
。然后尝试将按钮操作从 self.toggle
更改为 { a.isDone.toggle() }
所以您的列表如下所示。
List(listItems) { a in
Button(action: {
a.isDone.toggle()
}){
HStack {
Image(systemName: a.isDone ? "checkmark.circle.fill" : "circle")
Text(a.text)
}
}
}.offset(y: -50)
我有一个看起来像这样的列表:
但是当我点击一行时,每一行中的每个圆圈都会得到 activated/deactivated。我现在在这个问题上坐了几个小时,不知道该怎么做。谁能帮帮我?
我认为问题与 DispatchQueue.main.async
行有关。但是如果我在代码中不使用DispatchQueue.main.async
,列表是空的,无法填充。如果我不这样做 DispatchQueue.main.async
,我会收到两次以下错误:
Modifying state during view update, this will cause undefined behavior.
所以如果我使用 DispatchQueue.main.async
列表可以被填充并且不是空的。但正如我之前所述,新问题是,当我单击一行时,列表中的每个圆(来自所有行)都会得到 activated/deactivated.
这是我的代码:
struct zettelDetailView: View {
var info: CreateInfo
@State var isChecked: Bool = false
func toggle(){
isChecked = !isChecked
}
@State var listItems = [CreateZettelDetailViewText]()
@State var executeThisAsyncThing: Bool = true
private func changeInfoListToArray() {
//String ist folgendermaßen aufgebaut:
//"Text/-t;" t = true; f = false "/-" und ";" sind splitter
// var returnArray = [CreateZettelDetailViewText]()
// let infoStr = info.list
let infoStr = "Das-t;Ist-f;Ein-f;Test-t;"
let infoArr1 = infoStr.split(separator: ";")
var infoArr2 = [[String]]()
print(infoArr1.count)
if infoArr1.count != 0 {
for i in 0...(infoArr1.count - 1) {
let x = infoArr1[i]
let y = x.split(separator: "-")[0] //text
let z = x.split(separator: "-")[1] //bool
var arr2 = [String]()
arr2.append(String(y))
arr2.append(String(z))
var zBool: Bool = false
if z == "t" {
zBool = true
} else if z == "f" {
zBool = false
}
infoArr2.append(arr2)
self.listItems.append(CreateZettelDetailViewText(text: "\(String(y))", isDone: zBool))
}
}
executeThisAsyncThing = false
}
var body: some View {
// listItems = changeInfoListToArray()
DispatchQueue.main.async {
if self.executeThisAsyncThing {
self.changeInfoListToArray()
}
}
return VStack {
VStack {
Text(info.name)
.font(.largeTitle)
Text("\(info.day) - \(info.time)")
}.offset(y: -50)
List(listItems) { a in
Button(action: self.toggle
// {
//
// if a.isDone {
// self.isChecked = true
// } else if !a.isDone {
// self.isChecked = false
// }
//
// print()
// print(a.id)
// print(a.text)
// print(a.isDone)
// print()
//
// }
){
HStack {
Image(systemName: self.isChecked ? "checkmark.circle.fill" : "circle")
Text(a.text)
}
}.onAppear() {
self.isChecked = true
}
}.offset(y: -50)
Button(action: addRow) {
Image(systemName: "plus.app.fill")
.offset(y: -20)
.font(.largeTitle)
}
}
}
private func addRow() {
// var arr = [[String]]()
// arr = getZettelData()
// arr.append(["ZettelName", "\(time)", "\(day)"])
//
// let defaults = UserDefaults.standard
// defaults.set(arr, forKey: "SavedZettelArray")
}
}
整个列表只有一个 isChecked
。每一行都使用相同的变量,因此当其中一个被点击时,所有的变量都会改变。
根据代码,列表中的每一项似乎都有一个 isDone
成员。尝试将图像名称的 self.isChecked
替换为 a.isDone
。然后尝试将按钮操作从 self.toggle
更改为 { a.isDone.toggle() }
所以您的列表如下所示。
List(listItems) { a in
Button(action: {
a.isDone.toggle()
}){
HStack {
Image(systemName: a.isDone ? "checkmark.circle.fill" : "circle")
Text(a.text)
}
}
}.offset(y: -50)