SwiftUI @State i .sheet () ios13 vs ios14
Witam Mam tutaj problem i nie mam spójnego zachowania między moim widokiem .sheet () podczas pracy na ios13 lub ios14
Mam taki widok:
@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)
}
}
Na iOS 13 działa to zgodnie z oczekiwaniami btn kliknij -> ustaw etykietę -> call sheet -> wyświetl "Etykietę" w widoku tekstowym.
Na ios14 otrzymałem pusty ciąg w self.label, gdy w zamknięciu arkusza, więc nic nie wyświetla.
Czy coś przegapiłem? Czy to błąd iOS 14, czy też źle to zrobiłem na ios13 i to zostało poprawione.
PS: Mam kilka innych zmiennych, które są przekazywane w zamknięciu, uprościłem to.
Odpowiedzi
Twój kod oczekuje kolejności aktualizacji / tworzenia widoku, ale generalnie jest on niezdefiniowany (i prawdopodobnie zmienił się w iOS 14).
Istnieje wyraźny sposób przekazywania informacji w arkuszu - użyj innego kreatora arkusza, tj. .sheet(item:...
Oto działający niezawodny przykład. Testowane z 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)
}
}
}
To naprawdę dziwne zachowanie w iOS 14, które nie wydaje się być udokumentowane.
Korzystając z innej odpowiedzi tutaj i komentarza do tego wątku , @Bindingrozwiązałem problem, ponieważ wydawało się to najczystszym i najbardziej SwiftUI-esq rozwiązaniem.
Nie mam pojęcia, dlaczego to zachowanie się zmieniło i wydaje się mniej intuicyjne niż wcześniej, więc zakładam, że to błąd!
Przykład:
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)
}
}
Zachowanie zmieniło się w SwiftUI 2.0, więc wpływa również na MacOS 11, samo dodanie powiązania do widoku rozwiązuje problem, nawet jeśli to powiązanie nigdy nie jest używane, co sprawia, że myślę, że jest to błąd implementacji. Dodatkowo samo użycie zmiennej stanu szczegółów w Text () w treści widoku również rozwiązuje ten problem.
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 ?? "") }
}
}
}