I am having an issue with trying to customize my gesture responder chain

I come from Cocoa/macOS & Mouse Events, and the concept of gestures has been tripping me up

Assumptions based on my research:

  • Instead of mouse events being passed to NSResponders, There are Tap, Press, and Gesture events. Tap and Press get passed to UIResponders, Gestures are passed to GestureRecognizers (owned by a UIView)

  • The difference between touchBegan/touchMoved/touchEnded and a Gesture recognizer depends on the speed of the finger? (uigesturerecognizers-vs-touchesbegan-touchesmoved-touchesended-accuracy). So if you tap, and slowly move, the underlying UIView receives the touchMoved events. If you Tap and drag quickly, a gesture is created and passed to the the GestureRecognizer of the underlying UIView. I am pretty uncertain on this one, so I am opening another SO question to address this issue

  • When I say "swipe left", I mean the opposite direction your finger goes, and I mean left as in the direction of the navigation animation. same with "swipe right".

I have a problem with my "Gestures" not being sent to the Gesture Recognizers I would like. (I originally thought that gestures went to the controllers, but I have since learned that isn't the case, and GestureRecognizers are owned by the Views)

View Hierarchy:

  • "Swipeable" UITabBarController (SwipeableTabBarController)
    • UIViewController
    • UIViewController
    • UIViewController (UIView)
      • PageViewController (_PageContentView and _UIQueueingScrollView)
        • CollectionViewController (CollectionView)

So here's what I am trying to make happen:

  • If you swipe anywhere on the screen, you will move between the 3 UIViewControllers (Thanks SwipeableTabBarController)
  • If you swipe right on the third right-most UIViewController, you will actually flip through the pages of the PageViewController)
  • If you swipe left on the third UIViewController (which holds the PageViewController), and you are in the left-most page of the PageViewController, you will go left into the second (middle) UIViewController

However,

  • Once you navigate to the right-most UIViewController, all swipe gestures are consumed by the UIQueueingScrollView on the UIPageViewController. This means that Once you are in the right-most view, you cannot swipe back left to the middle view. Swiping just flips between pages, (and in the case of being on the left page, nothing happens)

  • I have manually enumerated over subviews to find this UIQueueingScrollView, and removed all GestureRecognizers from it, and this allows the gestures to get passed up to the SwipeableTabBarController, so that you can swipe back to the middle view... But this of course breaks the UIPageViewController's scrolling

My Goal:

Somehow mutate the GestureRecognizers in the UIPageViewController (it looks like I have to do it on it's _UIQueueingScrollView), so that

  • if you are looking at the left-most page:

    • do a swipe left gesture:
      • will be passed to the GestureRecognizers in SwipeableTabBarController. Main UIViewControllers will swap
    • do a swipe right gesture:
      • will be passed to the GestureRecognizers in UIQueueingScrollView, and the pageview will flip to the next page
  • else if you are looking at any other page:

    • all swipe gestures passed to the UIQueueingScrollView

My biggest hangup is that I can't just override gesture receivers, I have to create new custom GestureRecognizers and manually attach them to my views... but then I don't know how to have these new custom GestureRecognizers pass the gestures up the view hierarchy

0 Answers