SwiftUI - programowo przedstawia arkusz

Aug 31 2020

Chciałbym, aby pojawił się arkusz modalny z kilkoma opcjami do wyboru przez użytkownika. (Arkusz udostępniania jest doskonałym przykładem.) Kiedy użytkownik dokona wyboru, arkusz opcji znika i pojawia się drugi arkusz z wybraną opcją. W przykładzie arkusza udostępniania, jeśli użytkownik wybierze opcję drukowania, arkusz udostępniania przesuwa się w dół i pojawia się arkusz wydruku.

Mogę sprawić, by arkusz opcji pojawił się dość łatwo. Ale nie wymyśliłem, jak sprawić, by pojawił się drugi arkusz. Próbowałem dołączyć arkusz do pustego widoku, a następnie użyłem UserDefaults, aby ustawić bool, który aktywuje drugi arkusz. Nic.

Pierwszy arkusz

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

SecondSheet

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

Próbowałem ustawić wartość bool pokazaną poniżej w .onAppear, ale nie jest ona wywoływana po odrzuceniu arkusza modalnego. Czy istnieje sposób, aby stwierdzić, kiedy widok nie jest już zakryty arkuszem? W UIKit byłoby to PresentationControllerDidDismiss (_ :). Oczywiście przy założeniu, że mój pomysł dołączenia drugiego arkusza do pustego widoku jest nawet wykonalny.

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

Odpowiedzi

2 Asperi Aug 31 2020 at 22:06

Oto demo możliwego podejścia - aktywujesz drugi arkusz w onDismisspierwszym. Testowane z 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")
                }
        }
    }
}

Aktualizacja:

Oto alternatywa, która działa również dla SwiftUI 1.0. Przetestowano z Xcode 11.4 / iOS 13.4 i 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")
                    })
        }
    }
}