hq.training's first-run tour is a horizontal pager — one page per thing to know, swiped through. On a phone, swiping back a page leaves the tour instead:
there's an issue in the tour that when I swipe left it exits and doesn't go back to previous slider page
Craft already has the rule that would prevent this, and applies it only to web entries. CraftHybrid.swift, gestureRecognizerShouldBegin:
guard let slot = nav.topViewController as? CraftHybridWebSlot else { return true }
// Over the page, only from its left edge: a swipe across the page is
// the page's (a carousel, a slider).
if gestureRecognizer !== nav.interactivePopGestureRecognizer {
let moved = (gestureRecognizer as? UIPanGestureRecognizer)?.translation(in: nav.view).x ?? 0
if gestureRecognizer.location(in: nav.view).x - moved > 32 { return false }
}The comment says exactly the right thing — a swipe across the page is the page's (a carousel, a slider) — and the guard returns true before reaching it whenever the top view controller is a native screen. So on iOS 26, where interactiveContentPopGestureRecognizer answers a swipe starting anywhere rather than at the edge, any horizontal swipe on a native screen pops it. A native screen cannot contain a pager, a carousel, a swipeable row or a horizontal chart.
What a native screen can ask for today: setOptions accepts title, largeTitle, hidden and tabBarHidden — nothing about gestures. So there is no way to opt out from the app side.
Two ways to fix it, either is fine for us:
- Apply the same 32pt edge rule to a native screen that contains a horizontally scrollable view — the content gesture is the one that needs it, and the reasoning is identical to the web case.
- Let a screen say so: a
swipeBackFromEdgeOnly(orcontentSwipeBack: false) onsetOptions, which the tour would set while it is past its first page.
Reproduction: a native screen holding a horizontal ScrollView with paging, pushed onto the stack, on iOS 26. Swipe right anywhere over it: the screen pops instead of the pager moving. The edge recognizer alone behaves correctly, so on iOS 25 and earlier only a swipe starting within 32pt misbehaves.