Search code examples
iosswiftuiios13

SwiftUI: How to present new views on clicking ActionSheet button?


I have an action sheet consist of three actions

  1. Action_1
  2. Action_2
  3. Cancel

If I tap on 'Action_1', My app should present ActionView_1(). If I tap on 'Action_2', My app should present ActionView_2().

I got this for presenting a view

.sheet(isPresented: $isAddSecretVisible){ActionView_1()}.

But this for presenting a view with a Button click.

I need the same action if tap on the Actionsheet button. Answer needs in SwiftUI

Thanks in advance.


Solution

  • You should define 2 State, each for each a sheet:

    @State var isMainActionPresented = false
    @State var isActionViewPresented = false
    

    And a State to determine witch actionSheet to present. So you can have an enum for that like:

    enum ActionViewMode {
        case first
        case second
    }
    

    And a helper extension on that:

    extension ActionViewMode {
        var view: some View {
            switch self {
                case .first: return ActionView1()
                case .second: return ActionView2()
            }
        }
    }
    

    Then on click of any Button or ActionSheet.Button, toggle the desired state. Look at the complete ContentView code below:

    @State var actionViewMode = ActionViewMode.first
    
    @State var isMainActionPresented = false
    @State var isActionViewPresented = false
    
    var body: some View {
        Button(action: {
            self.isMainActionPresented = true
        }) {
            Text("ActionSheet")
        }
        .actionSheet(isPresented: $isMainActionPresented) {
            ActionSheet(
                title: Text("Title"),
                message: Text("Message"),
                buttons: [
                    .default(
                        Text("Action_1"),
                        action: {
                            self.actionViewMode = .first
                            self.isActionViewPresented = true
                    }),
                    .default(
                        Text("Action_2"),
                        action: {
                            self.actionViewMode = .second
                            self.isActionViewPresented = true
                    }),
                    .cancel()
            ])
        }
        .sheet(isPresented: $isActionViewPresented) {
            self.actionViewMode.view
        }
    }
    

    SwiftUI will handle the rest.

    Note that you can't chain multiple sheets one after another, because each one overrides previous somehow.