0
votes

I'm trying to dynamically show a sheet when a Menu() button is pressed. The issue I'm facing is that it seems the activeSheet state variable is not updating when I change it via a button. This causes the wrong view to show until I update the state with a different variable in which then the proper view will show.

Code for generating the Menu and setting the active tab

@State private var activeSheet = Sheets.Settings
@State private var showingSheet = false

enum Sheets: String, CaseIterable {
    case Settings = "Settings",
         Add = "Add"
}

Menu(content: {
    ForEach(Sheets.allCases, id: \.self) { sheet in
        Button(sheet.rawValue, action: {
            activeSheet = sheet
            showingSheet.toggle()
        })
    }
},
label: {
    Image(systemName: "plus")
})

And my sheet modifier that will display the actual sheet

.sheet(isPresented: $showingSheet) {
    switch activeSheet {
        case .Settings :
            SettingsView(dismiss: $showingSheet, settings: $settings)
        case .Add :
            AddView()
    }
}

This code will present a sheet but it will only show the settings sheet until I trigger some other @State change. After that everything will work as expected.

1
In such scenario you need to use .sheet(item:) like in stackoverflow.com/a/61176759/12299030.Asperi

1 Answers

1
votes

You should use .sheet(item:) instead of .sheet(isPresented:), and to do so the enum needs to conform to Identifiable. This should work:

@State private var activeSheet: Sheets?
        
enum Sheets: String, CaseIterable, Identifiable {
    case Settings = "Settings",
    Add = "Add"
    var id: String {
        return self.rawValue
    }
}
        
var body: some View {
    Menu(content: {
        ForEach(Sheets.allCases, id: \.self) { sheet in
            Button(sheet.rawValue, action: {
                activeSheet = sheet
            })
        }
    },
    label: {
        Image(systemName: "plus")
    })
    .sheet(item: $activeSheet) { sheet in
        switch sheet {
        case .Settings:
            SettingsView(dismiss: $showingSheet, settings: $settings)
        case .Add:
            AddView()
        }
    }
}