ios – Swift UI Detect multiple gestures


I have a view SwiftUIView that displays a bunch of child views SomeView. Each SomeView has some elements that the user should be able to interact with and touch using a tap gesture. This sub view should also allow the user to hold down on it for a short period and then present a .sheet if the user held down for long enough. This works but there a few problems with this.

  1. Adding the long press gesture to each SomeView makes the scroll view in SwiftUIView unresponsive for some swipes.
  2. The long press gesture sometimes makes the tap gestures execute also.

I’d also like to add a swipe gesture recognizer to SomeView to detect right horizontal swipes. Im not sure how to do this and manage all these gestures at the same time. Maybe my approach is not the most sound for such requirements.

import SwiftUI

struct SwiftUIView: View {
    var body: some View {
        ScrollView {
            LazyVStack {
                ForEach(0..<7, id: \.self) { i in
                    SomeView()
                }
            }
        }
    }
}

struct SomeView: View {
    @State private var showSheet: Bool = false
    @State private var isPressingDown: Bool = false
    @State private var started: Bool = false
    
    var body: some View {
        VStack {
            
            Text("Button")
                .onTapGesture {
                    // do something
                }
        }
        .scaleEffect(isPressingDown ? 1.2 : 1.0, anchor: .leading)
        .padding(.vertical, isPressingDown ? 8 : 0)
        // add swipe gesture
        .onLongPressGesture(minimumDuration: .infinity) {
            
        } onPressingChanged: { starting in
            if starting {
                started = true
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.05){
                    if started {
                        withAnimation {
                            isPressingDown = true
                        }
                        DispatchQueue.main.asyncAfter(deadline: .now() + 0.25){
                            if isPressingDown {
                                UIImpactFeedbackGenerator(style: .medium).impactOccurred()
                                showSheet = true
                                withAnimation {
                                    isPressingDown = false
                                }
                            }
                        }
                    }
                }
            } else {
                started = false
                if isPressingDown {
                    withAnimation {
                        self.isPressingDown = false
                    }
                }
            }
        }
    }
}

Latest articles

spot_imgspot_img

Related articles

Leave a reply

Please enter your comment!
Please enter your name here

spot_imgspot_img