我有一个简单的模型声明:
struct Claim: Codable, Identifiable {
let id: String
var name: String
var isSelected: Bool? = nil // used for selecting claims in a list
}
AddClaimView 用于过滤出已存储在
role.claims
中的声明。 , 并将它们显示在一个列表中供用户选择添加到 role
.struct AddClaimView: View {
var claims: [Claim] // all possible claims
@Binding var role: Role
var claimsForAdding: [Claim] {
self.claims.filter { claim in
!self.role.claims.contains(claim)
}
}
var body: some View {
VStack {
Text("Add claim")
.font(.largeTitle)
ClaimsListRows(claims: self.claimsForAdding.sorted())
}
}
}
过滤由计算属性
claimsForAdding
完成。 ,问题来了。如何绑定(bind)计算属性
claimsForAdding
至@Binding var claims
在 ClaimsListRow
查看,然后将它们添加到 role.claims
?@State var claimsForAdding....
显然不适用于计算属性。struct ClaimsListRows: View {
@Binding var claims: [Claim]
var body: some View {
List(claims) { claim in
// set property isSelected = true when tapping a row
.....
呈现的 View
AddClaimView
在一张纸上:struct RoleDetailed: View {
@Binding var role: Role
@State var showAddClaim = false
@Binding var claims: [Claim]
var body: some View {
VStack(alignment: .leading) {
HStack {
Text(role.name)
.font(.largeTitle)
Spacer()
}
Text("id: " + role.id)
.font(.footnote)
.foregroundColor(Color.gray)
List {
ForEach(role.claims) { claim in
ClaimRow(claim: claim)
}
}
}.font(.headline).padding(10)
.navigationBarItems(trailing:
Button(action: {
self.showAddClaim.toggle()
}) {
Text("Add claim")
}.sheet(isPresented: self.$showAddClaim, onDismiss: {
print("dismissed")
}, content: {
AddClaimView(claims: self.claims, role: self.$role)
})
)
}
}
根据我收到的评论,这是新的
AddClaimView
:struct AddClaimView: View {
var claims: [Claim]
@Binding var role: Role
var claimsForAdding: [Claim] {
get {
self.claims.filter { claim in
!self.role.claims.contains(claim)
}
}
set {
var claims = self.claims
claims.removeAll(where: { claim in
newValue.contains(claim)
})
}
}
var body: some View {
VStack {
Text("Add claim")
.font(.largeTitle)
ClaimsListRows(claims: Binding<[Claim]>(
get: {
self.claims.filter {
claim in !self.role.claims.contains(claim)
}
.sorted(by: { $0.name < $1.name })
},
set: { newValue in
var claims = self.claims
claims.removeAll(where: { claim in
newValue.contains(claim)
})
self.role.claims = claims
}
))
}
}
}
最佳答案
您需要创建一个自定义 Binding
更新角色:
ClaimsListRows(claims: Binding<[Claim]>(
get: {
self.claims.filter {
claim in !self.role.claims.contains(claim)
}
.sorted(by: { $0.name < $1.name })
},
set: { newValue in
var claims = self.claims
claims.removeAll(where: { claim in
newValue.contains(claim)
})
self.role.claims = claims
}
))
关于binding - 如何在 SwiftUI 中绑定(bind)计算属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59738550/