SwiftUI - apresentar planilha programaticamente

Aug 31 2020

Eu gostaria que uma planilha modal aparecesse com várias opções para o usuário escolher. (A planilha de compartilhamento é um exemplo perfeito.) Quando o usuário faz uma seleção, a planilha de opções desaparece e uma segunda planilha aparece com a opção selecionada. No exemplo da folha de compartilhamento, se o usuário selecionar imprimir, a folha de compartilhamento desliza para baixo e a folha de impressão é exibida.

Posso fazer com que a folha de opções apareça com bastante facilidade. Mas ainda não descobri como fazer a segunda folha aparecer. Tentei anexar a planilha a uma visualização vazia e usei UserDefaults para definir o bool que ativa a segunda planilha. Nada.

Primeira Folha

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

Tentei definir o bool mostrado abaixo em .onAppear, mas ele não é chamado quando uma planilha modal é dispensada. Existe uma maneira de saber quando uma vista não está mais sendo coberta por uma folha? No UIKit, seria presentationControllerDidDismiss (_ :). Claro, isso pressupõe que minha ideia de anexar a segunda folha a uma vista vazia seja até viável.

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

Respostas

2 Asperi Aug 31 2020 at 22:06

Aqui está uma demonstração da abordagem possível - você ativa a segunda folha onDismissda primeira. Testado com 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")
                }
        }
    }
}

Atualizar:

Aqui está uma alternativa que funciona para o SwiftUI 1.0 também. Testado com Xcode 11.4 / iOS 13.4 e 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")
                    })
        }
    }
}