Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI Present View Modally via TabView?

I have a TabView set up as follows:

struct ContentView: View {
    @State private var selection = 0
    @State var newListingPresented = false

    var body: some View {
        TabView(selection: $selection){

            // Browse
            BrowseView()
                .tabItem {
                    VStack {
                        Image(systemName: (selection == 0 ? "square.grid.2x2.fill" : "square.grid.2x2"))
                    }
                }
                .tag(0)


            // New Listing
            NewListingView()
                .tabItem {
                    VStack {
                        Image(systemName: (selection == 1 ? "plus.square.fill" : "plus.square"))
                    }
                }
                .tag(1)

            // Bag
            BagView()
                .tabItem {
                    VStack {
                        Image(systemName: (selection == 2 ? "bag.fill" : "bag"))
                    }
                }
                .tag(2)

            // Profile
            ProfileView()
                .tabItem {
                    VStack {
                        Image(systemName: (selection == 3 ? "person.crop.square.fill" : "person.crop.square"))
                    }
                }
                .tag(3)
        }.edgesIgnoringSafeArea(.top)
    }
}

Question: How would I get the "New Listing" tab to present NewListingView modally (called sheet in SwiftUI?) when tapped?

like image 597
Steven Schafer Avatar asked Mar 03 '23 00:03

Steven Schafer


1 Answers

If I correctly understood your goal you could consider the following approach, based on idea of using thing wrapper view which will present target view as a sheet...

Here it goes:

struct SheetPresenter<Content>: View where Content: View {
    @Binding var presentingSheet: Bool
    var content: Content
    var body: some View {
        Text("")
            .sheet(isPresented: self.$presentingSheet, content: { self.content })
            .onAppear {
                DispatchQueue.main.async {
                    self.presentingSheet = true
                }
            }
    }
}

and usage for your case is...

// New Listing
    SheetPresenter(presentingSheet: $newListingPresented, content: NewListingView())
    .tabItem {
        VStack {
            Image(systemName: (selection == 1 ? "plus.square.fill" : "plus.square"))
        }
    }
    .tag(1)

If you will need to to change tab selection after work in sheet you could pass some additional argument in SheetPresenter and use it in sheet's onDismiss: (() -> Void)? callback.

like image 180
Asperi Avatar answered Mar 05 '23 16:03

Asperi