9

I want to call different action sheets in a view, using a variable. That does not mean to work.

.actionSheet(isPresented: self.$neuinitialisierung) {
                ActionSheet(
                    title: Text("Testtitel 1"),
                    message: Text("Testmessage 1"),
                    buttons: [
                        .default(Text("Button 1"),
                                 action: {
                                    print("KLICK")
                        }),
                        .default(Text("Button 2"),
                        action: {
                            self.clouddienst_waehlen = true;
                        })
                        ])
            }
.actionSheet(isPresented: self.$clouddienst_waehlen) {
                ActionSheet(
                    title: Text("Testtitel 2"),
                    message: Text("Testmessage 2"),
                    buttons: [
                        .default(Text("Button 1"),
                                 action: {
                                    print("KLICK")
                        }),
                        .default(Text("Button 2"),
                        action: {
                            self.clouddienst_waehlen = true;
                        })
                        ])
            }

If I try it with just one action sheet, it works. How can I use the second?

CodierGott
  • 471
  • 1
  • 5
  • 10
  • Does this answer your question? [Multiple sheet(isPresented:) doesn't work in SwiftUI](https://stackoverflow.com/questions/58837007/multiple-sheetispresented-doesnt-work-in-swiftui) – Evgeny Aleksandrov Sep 01 '20 at 15:45

3 Answers3

5

No need for any of these complicated solutions. Just attach your .actionSheets to different views. It doesn’t need to be on the root level. You can use the .actionSheet modifier on a button for example.

Maciej Swic
  • 11,139
  • 8
  • 52
  • 68
4

I came up with this solution:

@State var showingMenu = false
@State var optionsMenu: OptionsMenu = .main

enum OptionsMenu { case main, export }

...

.actionSheet(isPresented: $showingMenu) {
    if self.optionsMenu == .main {
        return ActionSheet(title: Text("Main Menu"), buttons: [
            .default(Text("Export Menu")) {
                delay(0.1) {
                    self.optionsMenu = .export
                    self.showingMenu = true
                }
            }
            .destructive(Text("Close"))
        ])
    } else {
        return ActionSheet(title: Text("Export Menu"), buttons: [
            .default(Text("Export timeline as GPX")) {
                // TODO
            },
            .default(Text("Export timeline as JSON")) {
                // TODO
            },
            .destructive(Text("Close"))
        ])
    }
}

And the button that opens the first menu needs to make sure to reset the enum value, otherwise the wrong menu will open on next button tap:

Button(action: {
    self.optionsMenu = .main
    self.showingMenu = true
}) {
    Image(systemName: "ellipsis")
}
sobri
  • 1,626
  • 15
  • 28
1

You can use:

func actionSheet<T>(item: Binding<T?>, content: (T) -> ActionSheet) -> some View where T : Identifiable

It takes a Binding to some kind of optional and if the value is not nil presents an ActionSheet. Instead of setting your a flag to true, you would set this optional to some value.

LuLuGaGa
  • 13,089
  • 6
  • 49
  • 57