CodierGott
CodierGott

Reputation: 491

swiftui one view with 2 or 3 actionsheets?

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?

Upvotes: 10

Views: 2262

Answers (3)

Maciej Swic
Maciej Swic

Reputation: 11359

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.

Upvotes: 8

sobri
sobri

Reputation: 1685

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

Upvotes: 4

LuLuGaGa
LuLuGaGa

Reputation: 14388

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.

Upvotes: 1

Related Questions