web-dev-qa-db-fra.com

La feuille multiple (isPresented :) ne fonctionne pas dans SwiftUI

J'ai cette ContentView avec deux vues modales différentes, donc j'utilise sheet(isPresented:) pour les deux, mais il semble que seule la dernière soit présentée. Comment pourrais-je résoudre ce problème? Ou n'est-il pas possible d'utiliser plusieurs feuilles sur une vue dans SwiftUI?

struct ContentView: View {

    @State private var firstIsPresented = false
    @State private var secondIsPresented = false

    var body: some View {

        NavigationView {
            VStack(spacing: 20) {
                Button("First modal view") {
                    self.firstIsPresented.toggle()
                }
                Button ("Second modal view") {
                    self.secondIsPresented.toggle()
                }
            }
            .navigationBarTitle(Text("Multiple modal view problem"), displayMode: .inline)
            .sheet(isPresented: $firstIsPresented) {
                    Text("First modal view")
            }
            .sheet(isPresented: $secondIsPresented) {
                    Text("Only the second modal view works!")
            }
        }
    }
}

Le code ci-dessus se compile sans avertissements (Xcode 11.2.1).

19
turingtested

Veuillez essayer ci-dessous le code

enum ActiveSheet {
   case first, second
}

struct ContentView: View {

    @State private var showSheet = false
    @State private var activeSheet: ActiveSheet = .first

    var body: some View {

        NavigationView {
            VStack(spacing: 20) {
                Button("First modal view") {
                    self.showSheet = true
                    self.activeSheet = .first
                }
                Button ("Second modal view") {
                    self.showSheet = true
                    self.activeSheet = .second
                }
            }
            .navigationBarTitle(Text("Multiple modal view problem"), displayMode: .inline)
            .sheet(isPresented: $showSheet) {
                if self.activeSheet == .first {
                    Text("First modal view")
                }
                else {
                    Text("Only the second modal view works!")
                }
            }
        }
    }
}
16
Rohit Makwana

Votre cas peut être résolu par ce qui suit (testé avec Xcode 11.2)

var body: some View {

    NavigationView {
        VStack(spacing: 20) {
            Button("First modal view") {
                self.firstIsPresented.toggle()
            }
            .sheet(isPresented: $firstIsPresented) {
                    Text("First modal view")
            }
            Button ("Second modal view") {
                self.secondIsPresented.toggle()
            }
            .sheet(isPresented: $secondIsPresented) {
                    Text("Only the second modal view works!")
            }
        }
        .navigationBarTitle(Text("Multiple modal view problem"), displayMode: .inline)
    }
}
8
Asperi

Peut également ajouter la feuille à un EmptyView placé en arrière-plan de la vue. Cela peut être fait plusieurs fois:

  .background(EmptyView()
        .sheet(isPresented: isPresented, content: content))
4
Tylerc230

Vous pouvez accomplir cela simplement en regroupant le bouton et les appels .sheet ensemble. Si vous avez un premier et un arrière, c'est aussi simple que cela. Cependant, si vous avez plusieurs éléments de navigation dans le début ou la fin, vous devez les envelopper dans un HStack et également envelopper chaque bouton avec son appel de feuille dans un VStack.

Voici un exemple de deux boutons de fin:

            trailing:
            HStack {
                VStack {
                    Button(
                        action: {
                            self.showOne.toggle()
                    }
                    ) {
                        Image(systemName: "camera")
                    }
                    .sheet(isPresented: self.$showOne) {
                        OneView().environment(\.managedObjectContext, self.managedObjectContext)
                    }
                }//showOne vstack

                VStack {
                    Button(
                        action: {
                            self.showTwo.toggle()
                    }
                    ) {
                        Image(systemName: "film")
                    }
                    .sheet(isPresented: self.$showTwo) {
                        TwoView().environment(\.managedObjectContext, self.managedObjectContext)
                    }
                }//show two vstack
            }//nav bar button hstack
2
user2698617

En plus de réponse de Rohit Makwana , j'ai trouvé un moyen d'extraire le contenu de la feuille vers une fonction parce que le compilateur avait du mal à vérifier le type de mon gigantesque View.

extension YourView {
    enum Sheet {
        case a, b
    }

    @ViewBuilder func sheetContent() -> some View {
        if activeSheet == .a {
            A()
        } else if activeSheet == .b {
            B()
        }
    }
}

Vous pouvez l'utiliser de cette façon:

.sheet(isPresented: $isSheetPresented, content: sheetContent)

Il rend le code plus propre et soulage également le stress de votre compilateur.

0
cayZ