J'ai regardé des vidéos de la WWDC et des documents Apple sur la liaison de données, et selon ma compréhension actuelle, @State en tant que délégué de propriété fournira une connexion de liaison entre la vue et la propriété annotée, par exemple:
@State var myText: String
var body: some View {
VStack {
TextField($myText, placeholder: Text("input"))
Text(myText)
}
}
Cela liera monTexte avec le contenu du champ de texte que j'ai ajouté (c'est-à-dire que l'un change l'autre suivra pour mettre à jour)
Cependant, bien que je sache que $ myText fait référence au type de liaison de Binding, j'ai remarqué que Binding est également un délégué de propriété, et j'ai remarqué qu'il apparaît dans certains exemples de code d'Apple. Je ne sais pas à quoi cela sert en tant que délégué immobilier. @State fait déjà la liaison, alors pourquoi avons-nous besoin de @Binding? Apple docs suce pour l'instant à ce sujet.
Selon cette conférence WWDC (flux de données via Swift UI):
https://developer.Apple.com/wwdc19/226
@State
Doit être utilisé pour les modifications locales/privées dans un View
. Idéalement, ils seraient privés.
@Binding
Doit être utilisé dans les sous-vues/composants réutilisables lorsque la valeur habite outside
le domaine d'affichage actuel.
Vous pouvez le voir dans presentation(:_)
API.
Il y a probablement un tas d'états à l'intérieur, qui indiquent à SwiftUI
comment les afficher - mais la décision de si cela doit apparaître ou non dépend de la vue d'ensemble, d'où le @Binding
(isShowing
) que vous devez fournir.
@State n'est qu'un autre @propertyWrapper qui décrit une source de vérité .
"... Lorsque vous utilisez state, le framework alloue un stockage de persistance pour la variable et le suit comme une dépendance ... vous devez toujours spécifier une valeur constante initiale" - WWDC19 Session 226 (07:41)
@Binding encore un autre @propertyWrapper qui dépend explicitement de l'état.
"... En utilisant l'encapsuleur de propriété de liaison, vous définissez une dépendance explicite à une source de vérité sans la posséder, en outre, vous n'avez pas besoin de spécifier une valeur initiale car la liaison peut être dérivée de l'état." - WWDC19 session 226 (13:01)
Binding<T>
est le délégué de propriété de @Binding
.
$ myText vous donne un Binding<String>
.
La façon dont @State
"fait un travail de reliure" comme vous l'avez décrit, c'est pour vous donner un Binding<String>
initialisé avec un getter/setter qui capture la référence d'une instance de State<T>
.
Maintenant TextField
mute la valeur de myText en appelant le setter de la liaison pass-in, qui à son tour appelle le setter de State<T>
qui définit réellement myText.
Comme vous pouvez le voir, la liaison n'a pas besoin d'avoir la propriété stockée réelle, elle délègue à une autre instance qui a le stockage, qui dans ce cas est @State
. D'où le nom.
@State fait déjà le travail de liaison, alors de quoi avons-nous besoin @Binding pour
@State
ne crée pas la liaison par vous-même. Il a un public var binding: Binding<Value>
propriété qui ( docs ):
Utilisez une liaison pour créer une connexion bidirectionnelle entre une vue et son modèle sous-jacent.
(dans votre cas entre String
et TextField
)
Ainsi, les états binding
pour la valeur de liaison d'avant en arrière et les @State
en utilisant pour lire et muter la valeur et il fournit le binding
sur la valeur qu'il stocke.