sup*_*cio 7 data-binding binding ios swift swiftui
我不能理解如何在SwiftUI @Binding中结合使用ForEach。假设我要Toggle根据布尔数组创建s 的列表。
struct ContentView: View {
@State private var boolArr = [false, false, true, true, false]
var body: some View {
List {
ForEach(boolArr, id: \.self) { boolVal in
Toggle(isOn: $boolVal) {
Text("IsOn")
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我不知道如何将绑定传递给数组中的布尔对象Toggle。上面的代码给出此错误:
使用未解决的标识符“ $ boolVal”
好的,这对我来说很好(当然)。我试过了:
struct ContentView: View {
@State private var boolArr = [false, false, true, true, false]
var body: some View {
List {
ForEach($boolArr, id: \.self) { boolVal in
Toggle(isOn: boolVal) {
Text("IsOn")
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这次错误是:
在'ForEach'上引用初始化程序'init(_:id:content :)'要求'Binding'符合'Hashable'
有办法解决这个问题吗?
大多数答案(包括@kontiki 接受的答案)方法会导致引擎在每次更改时重新渲染整个 UI,Apple 在wwdc2021(大约时间 7:40)提到这是一种不好的做法
在这个版本的 swift 中,您可以通过传入可绑定项直接使用绑定数组元素,例如:
?? 请注意,iOS 14 及更低版本不支持 Swift 5.5,但至少检查操作系统版本,不要继续这种不良做法!
如果您还需要更改Toggles的数量(不仅是它们的值),请考虑这一点。顺便说一句,我们可以省略ForEach{} 块。
struct ContentView: View {
@State var boolArr = [false, false, true, true, false]
var body: some View {
NavigationView {
// id: \.self is obligatory if you need to insert
List(boolArr.indices, id: \.self) { idx in
Toggle(isOn: self.$boolArr[idx]) {
Text(self.boolArr[idx] ? "ON":"OFF")
}
}
.navigationBarItems(leading:
Button(action: { self.boolArr.append(true) })
{ Text("Add") }
, trailing:
Button(action: { self.boolArr.removeAll() })
{ Text("Remove") })
}
}
}
Run Code Online (Sandbox Code Playgroud)
在SwiftUI中,仅使用Identifiable结构而不是Bools
struct ContentView: View {
@State private var boolArr = [BoolSelect(isSelected: true), BoolSelect(isSelected: false), BoolSelect(isSelected: true)]
var body: some View {
List {
ForEach(boolArr.indices) { index in
Toggle(isOn: self.$boolArr[index].isSelected) {
Text("Is on")
}
}
}
}
}
struct BoolSelect: Identifiable {
var id = UUID()
var isSelected: Bool
}
Run Code Online (Sandbox Code Playgroud)
您可以使用类似下面的代码。请注意,您将获得不赞成使用的警告,但要解决此问题,请检查其他答案:https : //stackoverflow.com/a/57333200/7786555
import SwiftUI
struct ContentView: View {
@State private var boolArr = [false, false, true, true, false]
var body: some View {
List {
ForEach(boolArr.indices) { idx in
Toggle(isOn: self.$boolArr[idx]) {
Text("boolVar = \(self.boolArr[idx] ? "ON":"OFF")")
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)