SwiftUI @State und .sheet () ios13 vs ios14

Sep 17 2020

Hallo, ich habe hier ein Problem und habe kein konsistentes Verhalten zwischen meiner .sheet () -Ansicht, wenn ich auf ios13 oder ios14 ausgeführt werde

Ich habe eine Ansicht wie diese:

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

Auf ios 13 funktioniert dies wie erwartet, indem Sie auf -> Beschriftung festlegen -> Blatt aufrufen -> "Eine Beschriftung" in einer Textansicht anzeigen.

Auf ios14 habe ich beim Schließen des Blattes eine leere Zeichenfolge in self.label erhalten, daher wird nichts angezeigt.

Habe ich etwas verpasst Ist es ein iOS 14-Fehler oder habe ich es auf ios13 falsch gemacht und das wurde korrigiert.

PS: Ich habe ein paar andere Variablen, die im Abschluss übergeben werden. Ich habe es vereinfacht.

Antworten

4 Asperi Sep 18 2020 at 03:15

Ihr Code erwartet die Reihenfolge der Aktualisierung / Erstellung der Ansicht, ist jedoch im Allgemeinen undefiniert (und wurde wahrscheinlich in iOS 14 geändert).

Es gibt eine explizite Möglichkeit, Informationen innerhalb eines Blattes zu übergeben - verwenden Sie einen anderen Blattersteller, z. .sheet(item:...

Hier arbeitet zuverlässiges Beispiel. Getestet mit 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

Dies ist ein wirklich seltsames Verhalten in iOS 14, das nicht dokumentiert zu sein scheint.

Mit der anderen Antwort hier und dem Kommentar zu diesem Thread habe ich @Bindingdas Problem gelöst, da es die sauberste und schnellste Lösung für SwiftUI-esq zu sein schien.

Ich habe keine Ahnung, warum sich dieses Verhalten geändert hat, und es scheint weniger intuitiv als zuvor zu sein, also gehe ich davon aus, dass es ein Fehler ist!

Ein Beispiel:

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

Das Verhalten hat sich mit SwiftUI 2.0 geändert, sodass es sich auch auf MacOS 11 auswirkt. Durch Hinzufügen einer Bindung zur Ansicht wird das Problem auch dann behoben, wenn diese Bindung nie verwendet wird. Daher denke ich, dass dies ein Implementierungsfehler ist. Darüber hinaus wird das Problem nur durch die Verwendung der Detailstatusvariablen in einem Text () im Hauptteil der Ansicht behoben.

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