1 year ago

#149989

test-img

BarryD

SwiftUI WATCH Drag Gesture sensitive over superview; only specified on subview

I've got an VStack in a View and one of the items in it is another View (created in a separate file because of it's complexity). Inside that subview, I have a ZStack which overlays several images, and on the top-most image I've specified a Drag gesture. The size of that top-level image is much smaller (horizontally) than the others.

I expect the drag to work only when I tap&drag that top image since that's where the gesture is defined. What I find is that I can tap&drag anywhere in the subview (or perhaps I should say in the part of the top view that is the subview) and it works.

Tap&drag outside of the ComplexZStackImage does not trigger the gesture.

Here's the code: Top level

struct TheTop: View {
    @State private var ...
    ...

    var body: some View {
        ScrollView {
            VStack {
                Text("Bla1")
                Text("Bla2")
                Toggle("Toglabel", isOn: $aVar)
                Slider(value: $aVar2, in: 15.0...100.0, step: 1.0)
                    .overlay {
                        Group {
                            Text("Bla3")
                                .frame(width: 45, height: 40)
                                .background(Color(.black))
                                .padding(20.0)
                        }   // Have to use a group to get this next one to work.
                        .allowsHitTesting(false)
                    }
                Spacer(minLength: 2)
/* --> */      ComplexZStackedImage(levelSetting: $passedVar)
                    .scaleEffect(1.5)
                    .overlay {
                        Group {
                            Text("Bla4")
                                .offset(x: -3, y: -3)
                                .font(.caption)
                        }   // Have to use a group to get this next one to work.
                        .allowsHitTesting(false)
                    }
                Spacer(minLength: 20)
                ... // more stuff
            }
            .navigationTitle("Control")
            .navigationBarTitleDisplayMode(.inline)
        }
        .onAppear {
            // set vars
        }
        .onChange(of: var1) { newValue in
            // stuff
        }
    }
}

And here's the contained-view code:

struct ComplexZStackedImage : View {
    @Binding var levelSetting : Float
    @State private var swipeOffset : Float = 0.0
    
    var aSwipe : some Gesture {
        DragGesture(minimumDistance: 5, coordinateSpace: .local)
            .onChanged { theValue in
                // Set swipeOffset based on theValue
                swipeOffset = ...
            }
            .onEnded { _ in
                // We use swipeOfset here instead of the value because it's been fixed.
                levelSetting += swipeOffset
                swipeOffset = 0.0 
            }
    }
// THE PROBLEM: tap&drag anywhere in this body triggeers the gesture.
//   The gesture is applied only on the last (top) item in the ZStack and I
//     expect the tap to have to occur in that image for the tap&drag to be seen.

    var body: some View {
        ZStack(alignment: .leading) {
            Image("RedImage")  // These two are the same size.
            Image("GreenImage")
                .frame(width: /* calculated value */, alignment: .leading)
                .clipped()
            Image("AnotherImage")
                .scaleEffect(1.25)
                .offset(x: 10)
            Image("MuchSmallerImageHorizonally")
                .alignmentGuide(HorizontalAlignment.leading) { _ in aVal + swipeOffset) }
                .frame(alignment: .leading)
                .gesture(aSwipe)
        }
    }

Your thoughts appeciated.

swiftui

watchkit

uiswipegesturerecognizer

0 Answers

Your Answer

Accepted video resources