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).
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!")
}
}
}
}
}
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)
}
}
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))
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
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.