SwiftUI - Blatt programmatisch präsentieren

Aug 31 2020

Ich möchte, dass ein modales Blatt mit mehreren Optionen angezeigt wird, aus denen der Benutzer auswählen kann. (Das Freigabeblatt ist ein perfektes Beispiel.) Wenn der Benutzer eine Auswahl trifft, verschwindet das Optionsblatt und ein zweites Blatt mit der ausgewählten Option wird angezeigt. Wenn der Benutzer im Freigabeblatt-Beispiel Drucken auswählt, wird das Freigabeblatt nach unten verschoben und das Druckblatt wird angezeigt.

Ich kann das Optionsblatt leicht genug anzeigen lassen. Aber ich habe nicht herausgefunden, wie ich das zweite Blatt erscheinen lassen kann. Ich habe versucht, das Blatt an eine leere Ansicht anzuhängen, und dann mit UserDefaults den Bool festgelegt, der das zweite Blatt aktiviert. Nichts.

Erstes Blatt

Button(action: {
   UserDefaults.standard.set(true, forKey: showSelectedOption)
   showOptionForm = true
}) {
   Image(systemName: "square.and.arrow.up")
}
.sheet(isPresented: $showOptionForm) {
   OptionView().environment(\.managedObjectContext, self.moc)
})

Zweites Blatt

EmptyView()
   .sheet(isPresented: $showSelectedOption) {
      SelectedOptionView().environment(\.managedObjectContext, self.moc)
}

Ich habe versucht, den unten in .onAppear gezeigten Bool einzustellen, aber er wird nicht aufgerufen, wenn ein modales Blatt verworfen wird. Gibt es eine Möglichkeit zu erkennen, wann eine Ansicht nicht mehr von einem Blatt abgedeckt wird? In UIKit wäre es PresentationControllerDidDismiss (_ :) gewesen. Dies setzt natürlich voraus, dass meine Idee, das zweite Blatt an eine leere Ansicht anzuhängen, sogar umsetzbar ist.

let showSelectedOption = UserDefaults.standard.bool(forKey: "showSelectedOption")

Antworten

2 Asperi Aug 31 2020 at 22:06

Hier ist eine Demo des möglichen Ansatzes - Sie aktivieren das zweite Blatt onDismissdes ersten. Getestet mit Xcode 12 / iOS 14.

struct DemoTwoSheets: View {
    @State private var firstSheet = false
    @State private var secondSheet = false
    var body: some View {
        VStack {
            Button("Tap") { self.firstSheet = true }
                .sheet(isPresented: $firstSheet, onDismiss: { self.secondSheet = true }) { Text("First sheet") } EmptyView() .sheet(isPresented: $secondSheet) {
                    Text("Second sheet")
                }
        }
    }
}

Aktualisieren:

Hier ist eine Alternative, die auch für SwiftUI 1.0 funktioniert. Getestet mit Xcode 11.4 / iOS 13.4 und Xcode 12b5 / iOS 14.

struct DemoTwoSheets: View {
    @State private var firstSheet = false
    @State private var secondSheet = false
    var body: some View {
        VStack {
            Button("Tap") { self.firstSheet = true }
                .sheet(isPresented: $firstSheet, onDismiss: { self.secondSheet = true }) { Text("First sheet") } .background(Color.clear .sheet(isPresented: $secondSheet) {
                        Text("Second sheet")
                    })
        }
    }
}