SwiftUI @State et .sheet () ios13 vs ios14

Sep 17 2020

Bonjour, je rencontre un problème ici et je n'ai pas de comportement cohérent entre ma vue .sheet () lors de l'exécution sur ios13 ou ios14

J'ai une vue comme celle-ci:

@State private var label: String = "" 
@State private var sheetDisplayed = false
///Some code
var body: some View {
   VStack {
      Button(action: {
         self.label = "A label"
         self.isDisplayed = true
      }) {
           Text("test")
       }
   }.sheet(isPresented: $sheetDisplayed, onDismiss: {
        self.label = ""
    }) {
        Text(self.label)
       }
 }

Sur iOS 13, ce travail comme prévu btn cliquez -> définir l'étiquette -> feuille d'appel -> afficher "une étiquette" dans une vue texte.

Sur ios14, j'ai une chaîne vide dans self.label lors de la fermeture de la feuille, donc elle n'affiche rien.

Ai-je manqué quelque chose? Est-ce un bogue iOS 14 ou est-ce que je me suis trompé sur ios13 et que cela a été corrigé.

PS: J'ai quelques autres variables qui sont passées dans la fermeture, je l'ai simplifiée.

Réponses

4 Asperi Sep 18 2020 at 03:15

Votre code s'attend à un ordre de mise à jour / création de vue, mais en général, il n'est pas défini (et probablement changé dans iOS 14).

Il existe un moyen explicite de transmettre des informations à l'intérieur de la feuille - utilisez un créateur de feuille différent, c'est-à-dire. .sheet(item:...

Voici un exemple fiable de travail. Testé avec Xcode 12 / iOS 14

struct ContentView: View {
    @State private var item: Item?

    struct Item: Identifiable {
        let id = UUID()
        var label: String = ""
    }

    var body: some View {
        VStack {
            Button(action: {
                self.item = Item(label: "A label")
            }) {
                Text("test")
            }
        }.sheet(item: $item, onDismiss: { self.item = nil }) { Text($0.label)
        }
    }
}
2 Othyn Oct 04 2020 at 21:59

C'est un comportement vraiment étrange dans iOS 14, qui ne semble pas être documenté.

En utilisant l' autre réponse ici et le commentaire sur ce fil , j'ai utilisé @Bindingpour résoudre le problème car il semblait la solution la plus propre et la plus SwiftUI-esq.

Je n'ai aucune idée de pourquoi ce comportement a changé, et il semble moins intuitif qu'avant, donc je suppose que c'est un bogue!

Un exemple:

struct MainView: View {
    @State private var message = ""
    @State private var showSheet = false

    var body: some View {
        Button(action: {
            self.message = "This will display the correct message"
            self.showSheet = true
        }, label: {
            Text("Test Button")
        })
        .sheet(isPresented: self.$showSheet) { SheetView(message: self.$message)
        }
    }
}

struct SheetView: View {
    @Binding var message: Int

    var body: some View {
        Text(self.message)
    }
}
valexa Nov 19 2020 at 11:06

Le comportement a changé avec SwiftUI 2.0, il affecte donc MacOS 11 également, le simple fait d'ajouter une liaison à la vue le corrige même lorsque cette liaison n'est jamais utilisée, ce qui me fait penser qu'il s'agit d'un bogue d'implémentation. De plus, le simple fait d'utiliser la variable d'état des détails dans un Text () dans le corps de la vue le corrige également.

struct MyViewController : View {

    @State var details: String?
    @State var showDetails = false

    //    @Binding var havingAbindingFixesIt: String?

    var body: some View {
        VStack {
            //            Text(details ?? "")
            Text("Tap here for details")
                .onTapGesture {
                    self.details = "These are the details"
                    self.showDetails.toggle()
                }
                .sheet(isPresented: $showDetails) { Text(details ?? "") }
        }
    }
}