paint-brush
Les 5 principaux wrappers de propriété de SwiftUI et comment les utiliser efficacementpar@tseitlin
3,473 lectures
3,473 lectures

Les 5 principaux wrappers de propriété de SwiftUI et comment les utiliser efficacement

par Mykhailo Tseitlin 9m2023/05/31
Read on Terminal Reader

Trop long; Pour lire

SwiftUI est un framework pour créer des interfaces utilisateur sur iOS et macOS. Avec SwiftUI, vous pouvez décrire ce que votre interface doit faire et ressembler, et le framework s'occupera du reste. SwiftUI a cinq wrappers de propriété principaux : @State, @Binding, @ObservedObject, @StateObject et @EnvironmentObject.
featured image - Les 5 principaux wrappers de propriété de SwiftUI et comment les utiliser efficacement
Mykhailo Tseitlin  HackerNoon profile picture
0-item
1-item


Salut! Je voudrais vous parler de SwiftUI, un framework pour créer des interfaces utilisateur sur iOS et macOS. Il est très pratique à utiliser car il utilise une approche déclarative de la programmation. Avec SwiftUI, vous pouvez décrire ce que votre interface doit faire et ressembler, et le framework s'occupera du reste.


L'un des éléments clés de SwiftUI est l'utilisation de wrappers de propriété. Ce sont des éléments fonctionnels qui vous permettent de fournir une logique supplémentaire pour les propriétés.


SwiftUI a cinq principaux wrappers de propriétés :

  1. @État

  2. @Obligatoire

  3. @ObjetObservé

  4. @StateObject

  5. @EnvironmentObject


Ils deviendront vos meilleurs amis dans le développement.


@État


@State vous permet de créer des propriétés qui peuvent être modifiées et, si nécessaire, de mettre à jour l'interface en fonction de ces modifications. Par exemple, si vous souhaitez créer un bouton qui change de couleur lorsqu'il est pressé, vous pouvez créer une variable @State pour stocker la couleur et l'ajouter au bouton :


 struct MyButton: View { @State var buttonColor = Color.blue var body: some View { Button("Press me!") { buttonColor = Color.red } .background(buttonColor) } }


@Obligatoire


@Binding vous permet d'utiliser une valeur stockée dans une partie du code dans une autre partie du code. Il est généralement utilisé dans SwiftUI pour transmettre une valeur d'une vue à une autre, leur permettant d'interagir les unes avec les autres. Par exemple, imaginons que nous ayons deux vues - l'une avec un champ de texte et l'autre avec un bouton. Nous voulons que le champ de texte soit mis à jour lorsque l'utilisateur appuie sur le bouton. Pour ce faire, nous pouvons utiliser @Binding :


 struct ContentView: View { @State private var text = "" var body: some View { VStack { TextField("Enter text", text: $text) Button("Update text") { text = "New text" } SecondView(text: $text) } } } struct SecondView: View { @Binding var text: String var body: some View { Text(text) } }


Dans cet exemple, @Binding est utilisé pour passer la valeur de $text (qui est dans ContentView ) à text (qui est dans SecondView ), ainsi lorsque l'utilisateur appuie sur le bouton, le champ de texte sera mis à jour et affichera le nouveau texte.


@ObjetObservé


@ObservedObject est utilisé pour marquer les propriétés qui sont observées et peuvent changer en fonction des changements de données externes. Ce wrapper de propriété s'abonne aux modifications de l'objet qui se conforme au protocole ObservableObject et met automatiquement à jour les parties pertinentes de l'interface si les données ont changé. Voici un bref exemple d'utilisation de @ObservedObject :

 class UserData: ObservableObject { @Published var name = "John" } struct ContentView: View { @ObservedObject var userData = UserData() var body: some View { VStack { Text("Hello, \(userData.name)!") TextField("Enter your name", text: $userData.name) } } }


Dans cet exemple, nous créons une classe appelée UserData, qui contient un nom @Published. Dans la structure ContentView, nous créons une propriété appelée userData avec le type UserData, en utilisant @ObservedObject. Nous affichons la valeur de userData.name dans un champ de texte et l'affichons à l'écran.


Lorsque l'utilisateur modifie la valeur dans le champ de texte, SwiftUI met automatiquement à jour la partie correspondante de l'interface, car la propriété name est publiée et observée à l'aide de @Published. Cela signifie que nous n'avons pas besoin de notre propre code pour mettre à jour l'interface, et nous permettons à SwiftUI de le faire pour nous.


Remarque : Si vous ne le savez pas, @Published est un wrapper de propriété du framework Combine qui peut être ajouté à une propriété de classe ou de structure, qui envoie automatiquement des notifications de toute modification de la valeur de cette propriété à toute personne qui s'y est abonnée . En d'autres termes, il s'agit d'un attribut d'assistance pour les propriétés qui peuvent être suivies pour les modifications.


@StateObject


@StateObject est un wrapper de propriété utilisé pour initialiser un objet de classe et le stocker dans l'état d'affichage de SwiftUI. Cela signifie que l'objet est stocké tant que la vue existe et qu'il est détruit avec elle. En règle générale, l'utilisation de @StateObject est plus pratique pour les objets de classe qui sont nécessaires pour plusieurs vues, pas une seule. Par exemple:


 class UserData: ObservableObject { @Published var name = "John" @Published var age = 30 } struct ContentView: View { @StateObject var userData = UserData() var body: some View { NavigationView { VStack { Text("Name: \(userData.name)") Text("Age: \(userData.age)") NavigationLink( destination: ProfileView(userData: userData), label: { Text("Edit Profile") }) } .navigationTitle("Home") } } } struct ProfileView: View { @ObservedObject var userData: UserData var body: some View { Form { TextField("Name", text: $userData.name) Stepper("Age: \(userData.age)", value: $userData.age) } .navigationTitle("Profile") } }


Dans cet exemple, UserData est un objet d'une classe qui contient plusieurs propriétés pouvant être utilisées dans plusieurs vues. La classe est marquée comme ObservableObject afin qu'elle puisse être utilisée avec @StateObject et @ObservedObject .


Dans ContentView, nous créons un nouvel objet UserData en utilisant @StateObject pour enregistrer l'état entre les transitions entre différentes vues. Dans ce cas, ContentView affiche les données utilisateur, les visualise et contient un lien vers une autre vue (ProfileView) qui peut être utilisée pour modifier les données utilisateur.


Dans ProfileView , nous avons accès au même objet UserData en utilisant @ObservedObject pour modifier les données utilisateur. Lorsque l'utilisateur modifie des données, elles sont automatiquement mises à jour dans ContentView car le même objet UserData est utilisé.


Remarque : utilisez @ObservedObject si vous avez besoin d'observer les modifications d'un objet de classe à partir d'une vue et @StateObject si vous devez enregistrer l'état d'un objet de classe qui affecte l'affichage de plusieurs vues.


Si vous utilisez @ObservedObject au lieu de @StateObject pour un objet nécessaire dans plusieurs vues, chaque vue aura sa propre instance de l'objet, ce qui peut entraîner des problèmes de synchronisation des données entre les vues. Par conséquent, dans ce cas, il est préférable d'utiliser @StateObject.


@EnvironmentObject


@EnvironmentObject est un wrapper de propriété pour transmettre des objets de données via la hiérarchie de vue SwiftUI. Il permet d'accéder à l'objet de données à partir de n'importe quelle vue de la hiérarchie SwiftUI qui appartient au conteneur d'environnement (par exemple, scène, vue, application, etc.). Par exemple, imaginons que nous ayons une application de gestion de liste de tâches. Nous pouvons avoir un ContentView racine qui contient une liste de tâches et la possibilité de créer de nouvelles tâches. Pour cela, nous créons une vue TaskListView séparée qui affiche la liste des tâches et un bouton pour ajouter de nouvelles tâches. Après avoir ajouté une nouvelle tâche, l'utilisateur doit être redirigé vers l'écran d'ajout de tâche, nous créons donc une vue AddTaskView distincte.


Pour transmettre l'objet UserManager aux trois vues, nous pouvons créer son instance dans ContentView , puis la transmettre en tant que paramètre à TaskListView et AddTaskView . Cependant, cela peut devenir un problème si nous décidons d'ajouter encore plus de vues imbriquées, car nous devrons faire passer UserManager par de nombreuses vues intermédiaires.


Au lieu de cela, nous pouvons utiliser @EnvironmentObject pour transmettre UserManager à travers la hiérarchie des vues. De cette façon, toutes les vues qui ont besoin d'accéder à UserManager peuvent simplement le déclarer en tant que @EnvironmentObject et l'utiliser au besoin.

 struct TaskManagerApp: App { @StateObject var userManager = UserManager() var body: some Scene { WindowGroup { ContentView() .environmentObject(userManager) } } } struct ContentView: View { var body: some View { NavigationView { TaskListView() } } } struct TaskListView: View { @EnvironmentObject var userManager: UserManager var body: some View { List(userManager.tasks) { task in TaskRow(task: task) } .navigationBarTitle("Tasks") .navigationBarItems(trailing: Button(action: { // Navigate to AddTaskView }) { Image(systemName: "plus") } ) } } struct AddTaskView: View { @EnvironmentObject var userManager: UserManager var body: some View { // Add new task using userManager } }


Ainsi, l'objet UserManager sera désormais automatiquement transmis à TaskListView et AddTaskView via @EnvironmentObject . Notez que nous pouvons modifier l'état de UserManager dans une vue et que les modifications seront automatiquement répercutées dans l'autre vue.



L'article couvrait les wrappers de base de la propriété SwiftUI : @State, @Binding, @ObservedObject, @StateObject, @EnvironmentObject.


Ces wrappers de propriétés constituent la base de l'utilisation de l'état de l'application dans SwiftUI. Utilisez cet article comme aide-mémoire pour avoir à portée de main les wrappers de propriétés de base, nécessaires au développement d'applications avec SwiftUI. En appliquant ces connaissances, vous pourrez créer des interfaces utilisateur plus complexes avec des états changeant dynamiquement et intégrer les données de vos modèles dans SwiftUI.