Tap gesture on "buried views" takes several seconds to respond

Dear all,

For a MacOS application in pure SwiftUI where I need to respond to clicks on items that are somewhat "buried" in a complex structure, including split views and scroll views. Concretely it is a list of items in a scroll view which is deeply embedded in a view structure made of split-views, scroll-views, etc. But the onTapGesture takes several seconds to fire.

The exact behaviour is quite bizarre :

  • When I click once on an item, the tap gesture event is received several seconds later.
  • When I click on the same (or another) item a second time, the event is received immediately.
  • If a click a third time the delay occurs again, and so forth. In the end, the problem arises one in two clicks with perfect regularity.

When the delay occurs, the app gets literally frozen with the spinning wait cursor and high CPU usage until the event is actually received. I tried to profile the app, and noticed that functions named like "hitTest" are called intensively.

I noticed that the actual delay depends these factors :

  • The depth of the view structure (the delay shortens each time I remove one level)
  • The number of items in the deepest level (the delay grows when I add more of the actual views that are clicked on)
  • Some containers like split-views of scroll-views make the delay longer as well.
  • Using a Button is somewhat better, but still slow (and I need double click anyway).

I tried to reproduce the problem in the simplest form, which is shown below. I'm sorry I cannot over-simplify it, because the problem is only perceptible when the structure becomes a bit complex. The two embedded scroll-views are intentional (I actually need that in the actual structure), and they make things particularly worse but are not absolutely necessary to reproduce the problem. In this example I put 200 items to click on, but in my real application I get delays of 3-4 seconds with just a few items in the list.

Here is the code:

struct TestContentView: View {
    var body: some View {
        HSplitView {
            Text("Left column")
            VSplitView {
                Text("Upper content")
                ScrollView(.horizontal) {
                    ScrollView(.vertical) {
                        VStack() {
                            ForEach((1...200), id: \.self) { i in
                                Text("Some item, click me !").onTapGesture {
                                    print("This takes ages, but only one in two...")
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
code-block

Using XCode 13.4 under Macos 12.4, on an Intel MBP.

Any help would be greatly appreciated.

Thanks !

Tap gesture on "buried views" takes several seconds to respond
 
 
Q