SwiftUI - présenter la feuille par programme

Aug 31 2020

Je voudrais qu'une feuille modale apparaisse avec plusieurs options parmi lesquelles l'utilisateur peut choisir. (La feuille de partage est un exemple parfait.) Lorsque l'utilisateur effectue une sélection, la feuille d'options disparaît et une deuxième feuille apparaît avec l'option sélectionnée. Dans l'exemple de feuille de partage, si l'utilisateur sélectionne l'impression, la feuille de partage glisse vers le bas et la feuille d'impression apparaît.

Je peux faire apparaître la feuille d'options assez facilement. Mais je n'ai pas compris comment faire apparaître la deuxième feuille. J'ai essayé de joindre la feuille à une vue vide, puis j'ai utilisé UserDefaults pour définir le booléen qui active la deuxième feuille. Rien.

Première feuille

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

Deuxième feuille

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

J'ai essayé de définir la valeur booléenne ci-dessous dans .onAppear, mais elle n'est pas appelée lorsqu'une feuille modale est rejetée. Existe-t-il un moyen de savoir quand une vue n'est plus couverte par une feuille? Dans UIKit, cela aurait été presentationControllerDidDismiss (_ :). Bien sûr, cela suppose que mon idée d'attacher la deuxième feuille à une vue vide est même réalisable.

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

Réponses

2 Asperi Aug 31 2020 at 22:06

Voici une démonstration de l'approche possible - vous activez la deuxième feuille dans la onDismisspremière. Testé avec 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")
                }
        }
    }
}

Mettre à jour:

Voici une alternative qui fonctionne également pour SwiftUI 1.0. Testé avec Xcode 11.4 / iOS 13.4 et 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")
                    })
        }
    }
}