У меня есть простая модель Заявка:
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
, и здесь возникает проблема. Как связать вычисляемое свойство 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
.....
Представление, представляющее 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
}
))
}
}
}