Question

I want to add some ui to the R4PageViewController such as buttons and a listview, but don't know the right way to do so, i decided play around with shouldReceiveTouch, but no success

here is my gesture recognizer sub class

@implementation R4SwipeGestureRecognizer

- (id)initWithPageViewController:(R4PageViewController *)pageViewController
{
    self = [super initWithTarget:pageViewController action:
            @selector(handleSwipeFrom:)
//            nil
            ];
  if (self) {
    self.pageViewController = pageViewController;
//      self.delegate = self.pageViewController;

//      self.cancelsTouchesInView = YES;
//      self.delaysTouchesBegan = YES;
//      self.delaysTouchesEnded = YES;
  }
  return self;
}

//- (void)handleSwipeFrom:(UISwipeGestureRecognizer *)recognizer {
//
//}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//     super.delegate = self.pageViewController;
    [super touchesBegan:touches withEvent:event];
  UITouch *touch = [touches anyObject];
  self.previousTouchPoint = [touch locationInView:self.view];
  self.previousTouchTime = CFAbsoluteTimeGetCurrent();
  self.state = (self.previousTouchPoint.x > 20) ? UIGestureRecognizerStatePossible : UIGestureRecognizerStateFailed;
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesMoved:touches withEvent:event];
  UITouch *touch = [touches anyObject];
  CGPoint location = [touch locationInView:self.view];

  if (self.state == UIGestureRecognizerStatePossible) {
    CGFloat dx = location.x - self.previousTouchPoint.x;
    CGFloat dy = location.y - self.previousTouchPoint.y;

    if (ABS(dx) > ABS(dy)) {
      self.state = UIGestureRecognizerStateBegan;

      // load view controllers
      if (dx > 0 && !self.pageViewController.previousViewContainer.viewController) {
        [self.pageViewController loadPreviousViewController];
      } else if (dx < 0 && !self.pageViewController.nextViewContainer.viewController){
        [self.pageViewController loadNextViewController];
      }

    } else {
      self.state = UIGestureRecognizerStateFailed;
    }
  } else if (self.state == UIGestureRecognizerStateBegan || self.state == UIGestureRecognizerStateChanged) {
    CFAbsoluteTime time = CFAbsoluteTimeGetCurrent();

    CGFloat deltaX = location.x - self.previousTouchPoint.x;
    CFAbsoluteTime deltaT = time - self.previousTouchTime;

    UIView *view = self.pageViewController.currentViewContainer;
    view.origin = CGPointMake(view.origin.x + deltaX, view.origin.y);

    // load view controllers
    if (view.origin.x > 0 && !self.pageViewController.previousViewContainer.viewController) {
      [self.pageViewController loadPreviousViewController];
    } else if (view.origin.x < 0 && !self.pageViewController.nextViewContainer.viewController){
      [self.pageViewController loadNextViewController];
    }

    view = self.pageViewController.previousViewContainer;
    view.origin = CGPointMake(view.origin.x + deltaX * self.pageViewController.sidePagesSpaceDelayRate, view.origin.y);

    view = self.pageViewController.nextViewContainer;
    view.origin = CGPointMake(view.origin.x + deltaX * self.pageViewController.sidePagesSpaceDelayRate, view.origin.y);

    self.velocity = deltaX / deltaT;
    self.previousTouchPoint = location;
    self.previousTouchTime = CFAbsoluteTimeGetCurrent();

    if (self.pageViewController.currentPage == 0 && self.pageViewController.currentViewContainer.origin.x > self.pageViewController.borderPageMaxIndent) {
      self.pageViewController.currentViewContainer.origin = CGPointMake(self.pageViewController.borderPageMaxIndent, self.pageViewController.currentViewContainer.origin.y);
    } else if (self.pageViewController.currentPage == self.pageViewController.numberOfPages-1 && self.pageViewController.currentViewContainer.origin.x < -self.pageViewController.borderPageMaxIndent) {
      self.pageViewController.currentViewContainer.origin = CGPointMake(-self.pageViewController.borderPageMaxIndent, self.pageViewController.currentViewContainer.origin.y);
    }

    [self.pageViewController didScrollToOffset:self.pageViewController.currentViewContainer.frame.origin.x];

    self.state = UIGestureRecognizerStateChanged;
  }
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesEnded:touches withEvent:event];
  if (self.state == UIGestureRecognizerStateBegan || self.state == UIGestureRecognizerStateChanged) {
    BOOL pageChanged = NO;

    UIView *curentVCView = self.pageViewController.currentViewContainer;
    if (curentVCView.origin.x > curentVCView.size.width / 2 && self.pageViewController.currentPage > 0) {
      [self.pageViewController shiftContainersLeft];
      pageChanged = YES;
    } else if (curentVCView.origin.x < -curentVCView.size.width / 2 && self.pageViewController.currentPage < self.pageViewController.numberOfPages-1) {
      [self.pageViewController shiftContainersRight];
      pageChanged = YES;
    } else if (ABS(self.velocity) > 1000) {
      if (self.velocity < 0) {
        if (self.pageViewController.currentPage < self.pageViewController.numberOfPages-1) {
          [self.pageViewController shiftContainersRight];
          pageChanged = YES;
        }
      } else if (self.pageViewController.currentPage > 0) {
        [self.pageViewController shiftContainersLeft];
        pageChanged = YES;
      }
    }

    [self.pageViewController animateToRestAndMakeAppearanceUpdates:^{
      self.state = UIGestureRecognizerStateEnded;
      if (pageChanged) {
        [self.pageViewController didScrollToPage:self.pageViewController.currentPage toController:self.pageViewController.currentViewContainer.viewController];
      }
    }];
  } else {
    self.state = UIGestureRecognizerStateCancelled;
  }
}

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

    CGPoint location = [touch locationInView:self.view];
     NSLog(@" y location : %f", location.y);
    if (location.y< 70 || location.y > 288)
    {
        return NO;
    }
  if (self.state == UIGestureRecognizerStateBegan || self.state == UIGestureRecognizerStateChanged) {
    return NO;
  } else {
    return YES;
  }
}

@end

and here is init function

@implementation R4PageViewController

- (id)initWithOptions:(NSDictionary *)options
{
    self.options = [options mutableCopy];
    self = [super initWithNibName:@"View" bundle:nil];
    if (self) {
        //      super.view.frame = CGRectMake(0, 70, 320, 288);
        [self initializePrivateProperties];

        //      [self.view addSubview:[self getHeader]];

        self.view.backgroundColor = [UIColor whiteColor];
        self.view.layer.masksToBounds = YES;

        [self loadContainerViews];

        /* This guy provides swiping mechanism */
        R4SwipeGestureRecognizer *r = [[R4SwipeGestureRecognizer alloc] initWithPageViewController:self];
        [self.view addGestureRecognizer:r];
        self.swipeGestureRecognizer = r;


        r.delegate = self;

    }
    return self;
}

and here is a part from the header

//! R4PageViewController main class.
@interface R4PageViewController : UIViewController <UIGestureRecognizerDelegate>

@property (weak, nonatomic) id<R4PageViewControllerDataSource> dataSource;
@property (weak, nonatomic) id<R4PageViewControllerDelegate> delegate;
@property (strong, nonatomic, readonly) UIViewController *currentViewController;
@property (assign, nonatomic) NSInteger currentPage;

// Methods
- (id)initWithOptions:(NSDictionary *)options;
- (void)reloadData;

@end

my problem: shouldReceiveTouch is never called

here is an image to simplify the ideaenter image description here

Was it helpful?

Solution

I figured the problem

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

    CGPoint location = [touch locationInView:self.view];
     NSLog(@" y location : %f", location.y);
    if (location.y< 70 || location.y > 288)
    {
        return NO;
    }
  if (self.state == UIGestureRecognizerStateBegan || self.state == UIGestureRecognizerStateChanged) {
    return NO;
  } else {
    return YES;
  }
}

This function should be placed at the view controller (R4PageViewController) implementation not within the delegator (R4SwipeGestureRecognizer)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top