SwiftUI Gestures prevent scrolling with iOS 18

I added gesture support to my app that supports iOS 16 and 17 and have never had issues with it.

However, when I compiled my app with Xcode 16 I immediately noticed a problem with the app when I ran it in the simulator. I couldn't scroll up or down. I figured out it’s because of my gesture support.

My gesture support is pretty simple.

        let myDragGesture = DragGesture()
            .onChanged { gesture in
                self.offset = gesture.translation
            }
            .onEnded { _ in
                    if self.offset.width > threshold {
                       ...some logic
                    } else if self.offset.width < -threshold {
                       ...some other logic
                    }
                              
                logitUI.debug("drag gesture width was \(self.offset.width)")
                self.offset = .zero
            }

If I pass nil to .gesture instead of myDragGesture then scrolling starts working again.

Here’s some example output when I’m trying to scroll down. These messages do NOT appear when I run my app on an iOS 16/17 simulator with Xcode 15.

  • drag gesture width was 5.333328
  • drag gesture width was -15.333344
  • drag gesture width was -3.000000
  • drag gesture width was -24.333328
  • drag gesture width was -30.666656

I opened FB14205678 about this.

Thanks for flagging this @shiftingsand. Your bug report is being investigated, please continue to test on the latest beta and verify if you still see the same behavior or not and include your results as part of your bug report.

No change with Version 16.0 beta 5 (16A5221g).

No change with Version 16.0 beta 6 (16A5230g).

I also have this issue, no change in Xcode 16 RC and iOS 18 RC. this is very disappointing and will break a lot of apps. What's up apple? Or am I missing something how to fix this?

I have a horizontal scroll view and each view has a drag gesture which on vertical drag would dismiss the view. This worked in iOS 17.5 and Xcode 15.4 but not on the latest as I mention above.

My fix is to use .simultaneousGesture rather than just .gesture modifier block, it seems to work and the view is more dynamic as the horizontal scroll and individual view's drag gestures work together simultaneously rather than one or the other. Is this the intended behavior Apple wants? That's fine, but more explanation and documentation would really go a long way to help here.

Suffering the same, all our app is broken, and using .simultaneousGesture unlocks a dance of gestures.

Same problem in my app. I develop a comic read app, use UIPageViewController as basic reader. And I add a clear layer with tap gesture, when user tap center area, will open a control panel to adjust reading preference. But now I can't scroll UIPageViewController by swipe gesture.

here is a simple version of my code:

struct TestFunctionView: View {
    var body: some View {
        ZStack {
            TabView {
                Text("1")
                Text("2")
            }
            .tabViewStyle(.page)
            
            Rectangle()
                .foregroundColor(.clear)
                .contentShape(Rectangle())
                .onTapGesture(count: 1){
                    print("Tap")
                }
        }
    }
}

In iOS 17, both tap and scroll gesture can be trigger. but in iOS 18, it's not.

Really help apple can fix it, or it there another way to code my requirement?

C'mon Apple really?!

I have Images array with option to swipe horizontally and tap gesture to open image sometimes works some times it doesn't.

I found a solution:

.highPriorityGesture(
        TapGesture()
            .onEnded {
                // Tap logic
            }
    )

The real problem is that I need to check every tap gesture in my app because some works some doesn't... fix this quick!

iOS 18.0 (public)

Same here; all ScrollViews containing elements with DragGesture() don't scroll properly and this is causing major headaches. I've switched some from .highPriorityGesture() to .simultaneousGesture() as a stopgap measure.

To provide more information, it seems that .gesture() is not recognized on the current view but on the previous view in the navigation stack on an iOS 18 device.

I happened to support two different customized zoom gestures in my two views in the navigation stack, both are implemented based on .MagnifyGesture().

When I zoom on the second page, nothing happens; but when I navigated back to the previous page, I saw the zoom gesture had been triggered.

iOS 18.0, my app's custom implementation of swipeActions() for any views within vertical ScrollView is broken. Scroll through the a bunch of views on several screens is a pain now, because my highPriorityGestures is conflicting with ScrollView.

It works perfectly in iOS 16 and 17. The only thing I managed to do with this in iOS 18 is to increase minimumDistance for DragGesture, but this is just hiding the problem, not solving it.

It's great to have UIGestureRecognizerRepresentable now, but I hope it is not meaning that we have to handle all gestures in UIKit-way instead of SwiftUI-way, isn't it?

if you facing ScrollViews blocked ur tap/long press handle. u can try this code:

struct TestView: View {
    var body: some View {
        ZStack {
            Button("") {
                // Your tap press handler
                print("tap press")
            }
            
            // Replace Rectangle with the view you need
            Rectangle()
                .foregroundStyle(Color.white.opacity(0.011))
                .gesture(
                    LongPressGesture(minimumDuration: 0.5)
                        .onEnded { _ in
                            // Your long press handler
                            print("long press")
                        }
                )
        }
        .highPriorityGesture(
            TapGesture().sequenced(before: DragGesture())
        )
    }
}

the important code is add TapGesture().sequenced(before: DragGesture()) inside highPriorityGesture and handle the tap press inside Button action.

I'm still experiencing this issue. I need highPriorityGesture to prevent the subview gesture, but it's overriding the scroll view gesture. Can we cancel the high priority gesture to allow the scroll view to take over? In iOS 17, they work perfectly together.

Currently I set the minimum distance of the high priority gesture to 30, but that's just a workaround I reckon.

SwiftUI Gestures prevent scrolling with iOS 18
 
 
Q