5

It's been a long day at the keyboard so I'm reaching out :-)

I have a UIPageViewController in a typical implementation that basically follows Apple's standard template. I am trying to add an overlay that will allow the user to do things like touch a button to jump to certain pages or dismiss the view controller to go to another part of the app.

My problem is that the UIPageViewController is trapping all events from my overlay subview and I am struggling to find a workable solution.

Here's some code to help the example...

In viewDidLoad

// Page creation, pageViewController creation etc....

self.pageViewController.delegate = self;

[self.pageViewController setViewControllers:pagesArray
                                  direction:UIPageViewControllerNavigationDirectionForward
                                   animated:NO
                                completion:NULL];

self.pageViewController.dataSource = self;

[self addChildViewController:self.pageViewController];
[self.view addSubview:self.pageViewController.view];

// self.overlay being the overlay view

if (!self.overlay) 
{
   self.overlay = [[MyOverlayClass alloc] init];  // Gets frame etc from class init
   [self.view addSubview:self.overlay];
}

This all works great. The overlay gets created, it gets show over the top of the pages of the UIPageViewController as you would expect. When pages flip, they flip underneath the overlay - again just as you would expect.

However, the UIButtons within the self.overlay view never get the tap events. The UIPageViewController responds to all events.

I have tried overriding -(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch per the suggestions here without success.

UIPageViewController Gesture recognizers

I have tried manually trapping all events and handling them myself - doesn't work (and to be honest even if it did it would seem like a bit of a hack).

Does anyone have a suggestion on how to trap the events or maybe a better approach to using an overlay over the top of the UIPageViewController.

Any and all help very much appreciated!!

Community
  • 1
  • 1
Hooligancat
  • 3,588
  • 1
  • 37
  • 55

2 Answers2

3

Try to iterate through UIPageViewController.GestureRecognizers and assign self as a delegate for those gesture and implement

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch;

Your code may be like this:

In viewDidLoad

for (UIGestureRecognizer * gesRecog in self.pageViewController.gestureRecognizers)
{
        gesRecog.delegate = self;
}

And add the following method:

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
    if (touch.view != self.pageViewController.view]
    {
        return NO;
    }
    return YES;
}
Bo Persson
  • 90,663
  • 31
  • 146
  • 203
Basem Saadawy
  • 1,808
  • 2
  • 20
  • 30
0

The documented way to prevent the UIPageViewController from scrolling is to not assign the dataSource property. If you assign the data source it will move into 'gesture-based' navigation mode which is what you're trying to prevent.

Without a data source you manually provide view controllers when you want to with setViewControllers:direction:animated:completion method and it will move between view controllers on demand.

The above can be deduced from Apple's documentation of UIPageViewController (Overview, second paragraph):

To support gesture-based navigation, you must provide your view controllers using a data source object.

King-Wizard
  • 15,628
  • 6
  • 82
  • 76