2 votes

Comment lier une propriété calculée dans SwiftUI

J'ai un modèle simple de réclamation :

struct Claim: Codable, Identifiable {
    let id: String
    var name: String

    var isSelected: Bool? = nil // used for selecting claims in a list
}

La vue AddClaim permet de filtrer les réclamations qui sont déjà stockées dans la base de données de l'UE. role.claims et les présenter dans une liste que l'utilisateur peut sélectionner pour les ajouter à la liste de diffusion. 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())
        }
    }
}

Le filtrage est effectué par la propriété calculée claimsForAdding et c'est là que le bât blesse. Comment puis-je lier la propriété calculée claimsForAdding a @Binding var claims dans le ClaimsListRow puis les ajouter à la vue role.claims ?

@State var claimsForAdding.... ne fonctionne évidemment pas pour une propriété calculée.

struct ClaimsListRows: View {
    @Binding var claims: [Claim]
    var body: some View {
        List(claims) { claim in
// set property isSelected = true when tapping a row
.....

La vue qui présente AddClaimView dans une feuille :

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)
            })
        )
    }

}

D'après les commentaires que j'ai reçus, il s'agit de la nouvelle 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
                }
            ))
        }
    }
}

7voto

Yonat Points 478

Vous devrez créer un Binding qui met à jour le rôle :

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
    }
))

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X