Search code examples
swiftuigesture

How to launch a View from a swiftui gesture


Gestures in ios 13 do not seem to allow using .sheet to launch a modal view nor does it allow use of .alert either. Alerts and Sheets seem to only work on buttons, images, and other objects, but not on gestures. Any idea of a workaround other than use buttons which have there own issues such as hiding.

                ZStack(alignment: .top) {
                    
                    MapView(currentTab: self.$selection, mapViewModel: self.mapViewModel)
                        .edgesIgnoringSafeArea(.all)
                        .environment(\.colorScheme, .light)
                        
                        .overlay(Rectangle()
                            .opacity(0.1)
                            //.background(Color.clear)
                            .background(Image("Cursor_Flecha_4.svg")
                                .resizable()
                                .aspectRatio(contentMode: .fit)
                                .scaledToFit()
                                //.frame(width: 32.0, height: 32.0))
                                .frame(width: geo.size.width, height: geo.size.height * 0.15))
                            
                            .border(Color.red, width: 4)
                            
                            .frame(width: geo.size.width, height: geo.size.height * 0.25)
                            
                            .gesture(
                                DragGesture(minimumDistance: 50)
                                    .onEnded { gesture in
                                        
                                if ((gesture.translation.width >= 50) && (abs(gesture.translation.height) <= 20)) {
                                    print("swipe right detected")
//                                    GetRouteName()
                                    .sheet(isPresented: self.$showView) {
                                        GetRouteName(onDismiss: {
                                            self.showView = false
                                            self.mapViewModel.saveRoute(coreDM: self.coreDM, routeName: self.routeName)
                                        }, routeName: self.$routeName) //.offset(y: self.showView ? 0 : 1000)
                                    }
                                } else {
       

Solution

  • You can't put .sheet inside your DragGesture().onEnded closure. Instead, create a state property and link it with your sheet.

    struct ContentView: View {
       @State private var showSheet = false 
       
       var body: some View {
          MapView(...)
             .gesture(
                 DragGesture()
                     .onEnded { gesture in 
                         if ((gesture.translation.width >= 50) && (abs(gesture.translation.height) <= 20)) {
                             print("swipe right detected")
    
                             self.showSheet = true
                         }
                     }
             )
             .sheet(isPresented: self.$showSheet) { ... }
       }