Paging With UIScreenEdgePanGestureRecognizer

20 / Apr / 2015 by Abhayam Rastogi 0 comments

How To Use UIScreenEdgePanGestureRecognizer for Paging in iPhone 5

Before we get started, let me give you a brief overview of how you use UIScreenEdgePanGestureRecognizers and why they’re so handy.
Using UIScreenEdgePanGestureRecognizers is extremely simple. You just perform the following steps:

  1. Create a screen edge pan gesture recognizer. When you create a gesture recognizer(screen edge pan gesture), you specify a callback method so the gesture recognizer can send you updates when the gesture starts, changes, or ends.This tutorial also assumes that you know how to use Interface Builder to add new objects to a view and connect outlets between your code

  2. Add the screen edge pan gesture recognizer to a view. Each gesture recognizer is associated with one (and only one) view. When a touch occurs within the bounds of that view, the gesture recognizer will look to see if it matches the type of touch it’s looking for, and if a match is found it will notify the callback method.

    This tutorial also assumes that you know how to use Interface Builder to add new objects to a view and connect outlets between your code

Paging With Screen Edge Pan Gesture Demo Video

In this sample video you can see how UIScreenPanGesture will work to implement paging.

Getting Started

First download the starter project for this PagingWithUIScreenEdgePanGesture tutorial here SampleProject-UIScreenEdgePanGesture. This project provides a basic UI to get you started – no UIScreenEdgePanGesture code has been added yet.

Paging With ScreenEdgePanGesture Code

Make the following changes to ViewController.m:

1. First you need to add the left and right view for paging. Add this to the top of ViewController.m, just underneath all the #import lines.

ProfileView *leftProfileView;
ProfileView *rightProfileView;

2. Create a UIScreenEdgePanGestureRecognizer in your project. We requires two
UIScreenEdgePanGestureRecognizer objects for left and right edge of screen. Add this to the top of ViewController.m, just underneath all the #import lines.

UIScreenEdgePanGestureRecognizer *leftEdgeGesture;
UIScreenEdgePanGestureRecognizer *rightEdgeGesture;

3. Create left & right edge gesture in -addGestureRecognizer method. Add these gestures to your self.view, so that it will work across the entire iPhone screen.

// Replace addGestureRecognizer with the following

- (void)addGestureRecognizer
{
    leftEdgeGesture = [[UIScreenEdgePanGestureRecognizer alloc]initWithTarget:self 
    action:@selector(handleLeftEdgeGesture:)];
    leftEdgeGesture.edges = UIRectEdgeLeft;
    leftEdgeGesture.delegate = self;
    [self.view addGestureRecognizer: leftEdgeGesture];

    rightEdgeGesture = [[UIScreenEdgePanGestureRecognizer alloc]initWithTarget:self 
    action:@selector(handleRightEdgeGesture:)];
    rightEdgeGesture.edges = UIRectEdgeLeft;
    rightEdgeGesture.delegate = self;
    [self.view addGestureRecognizer: rightEdgeGesture];
}

 

4. Handle Left UIScreenEdgePanGesture state. The complete logic to get other profile after swiping either through left or right edge is given below. Uncomment the lines of code from before:

- (void)handleLeftEdgeGesture:(UIScreenEdgePanGestureRecognizer*)gesture
{

    //These Lines below are commented
    CGPoint translation =  [gesture translationInView:gesture.view];
    CGFloat width = self.view.frame.size.width;
    CGFloat percent = MAX( [gesture translationInView:self.view ].x, 0)/width;
    switch(gesture.state) {
      case UIGestureRecognizerStateBegan:
      { 
       if(--currentIndex <0){
          return;
         }
         CGRect leftProfileViewFrame = CGRectMake(-screenWidth,0,screenWidth,screenHeight);
         leftProfileView = [[ProfileView alloc]initWithFrame:leftProfileViewFrame
                                                            withArray:photosUrlArray
                                                           currentIndex:currentIndex];
         [self.view addSubview:leftProfileView];
         UIBezierPath *shadowPath = [UIBezierPath bezierPathWithRect:leftProfileView.bounds];
         leftProfileView.layer.masksToBounds = NO;
         leftProfileView.layer.shadowColor = [UIColor blackColor].CGColor;
         leftProfileView.layer.shadowOffset = CGSizeMake(0.0f, 5.0f);
         leftProfileView.layer.shadowOpacity = 1;
         leftProfileView.layer.shadowPath = shadowPath.CGPath;
         }
         break;
       case UIGestureRecognizerStateChanged:
         if(currentIndex <0){
         return;
         }
         centerProfileView.frame = CGRectMake(0 + translation.x/3, 0, screenWidth, 480);
         leftProfileView.frame = CGRectMake(-screenWidth + translation.x, 0, screenWidth,480);
         [leftProfileView setUserInteractionEnabled:NO];
         [self.view setUserInteractionEnabled:NO];
         break;
       case UIGestureRecognizerStateEnded:
        if(currentIndex <0){
          currentIndex = 0;
           return;
        }
        if(percent > 0.5 || fabs([gesture velocityInView:self.view].x) > 1000)
        {           
         [UIView animateWithDuration:0.2 delay:0.0 
                                              options:UIViewAnimationOptionTransitionNone
                                              animations:^{         
         centerProfileView.frame=CGRectMake(screenWidth,self.view.frame.origin.y,screenWidth,screenHeight);
         leftProfileView.frame=CGRectMake(0, self.view.frame.origin.y,screenWidth,screenHeight);
         }completion:^ (BOOL completed) {
          [centerProfileView removeFromSuperview];
          centerProfileView = leftProfileView;
         }];
         }else{
          [UIView animateWithDuration:0.2 delay:0.0 options:
          UIViewAnimationOptionTransitionNone animations:^{
          centerProfileView.frame=CGRectMake(0 , self.view.frame.origin.y,screenWidth,screenHeight);
          leftProfileView.frame=CGRectMake(-screenWidth, self.view.frame.origin.y,screenWidth,screenHeight);
          } completion:^ (BOOL completed) { 
          [leftProfileView removeFromSuperview];
          leftProfileView = nil;
          currentIndex++;
          }];
         }
          [leftProfileView setUserInteractionEnabled:YES];
          [self.view setUserInteractionEnabled:YES];
          break;
         default:
          NSLog(@"unhandled state for gesture=%@", gesture);
    }
    
}

5. Handle Right UIScreenEdgePanGesture state.Uncomment the lines of code from before:

- (void)handleRightEdgeGesture:(UIScreenEdgePanGestureRecognizer*)gesture
{

 // These lines below are commented
    CGPoint translation =  [gesture translationInView:gesture.view];
    CGFloat width = self.view.frame.size.width;
    CGFloat percent = MAX( [-gesture translationInView:self.view ].x, 0)/width;
    switch(gesture.state) {
      case UIGestureRecognizerStateBegan:
      { 
       if(++currentIndex>=[photosUrlArray count]){
          return;
         }
         CGRect rightProfileViewFrame = CGRectMake(screenWidth , 0, screenWidth, screenHeight);
         rightProfileView = [[ProfileView alloc]initWithFrame:rightProfileView
                                                            withArray:photosUrlArray
                                                           currentIndex:currentIndex];
         [self.view addSubview:rightProfileView];
         UIBezierPath *shadowPath = [UIBezierPath bezierPathWithRect:rightProfileView.bounds];
         rightProfileView.layer.masksToBounds = NO;
         rightProfileView.layer.shadowColor = [UIColor blackColor].CGColor;
         rightProfileView.layer.shadowOffset = CGSizeMake(0.0f, 5.0f);
         rightProfileView.layer.shadowOpacity = 1;
         rightProfileView.layer.shadowPath = shadowPath.CGPath;
         }
         break;
       case UIGestureRecognizerStateChanged:
         if(currentIndex>=[photosUrlArray count]){
         return;
         }
         centerProfileView.frame = CGRectMake(0 + translation.x/3, 0, screenWidth, 480);
         rightProfileView.frame = CGRectMake(screenWidth + translation.x, 0, screenWidth,480);
         [rightProfileView setUserInteractionEnabled:NO];
         [self.view setUserInteractionEnabled:NO];
         break;
       case UIGestureRecognizerStateEnded:
        if(currentIndex>=[photosUrlArray count]){
          currentIndex = [photosUrlArray count]-1;
           return;
        }
        if(percent > 0.5 || fabs([gesture velocityInView:self.view].x) > 1000)
        {            
         [UIView animateWithDuration:0.2 delay:0.0 
                                              options:UIViewAnimationOptionTransitionNone
                                              animations:^{         
         centerProfileView.frame=CGRectMake(-screenWidth,self.view.frame.origin.y,screenWidth,screenHeight);
         rightProfileView.frame=CGRectMake(0, self.view.frame.origin.y,screenWidth,screenHeight);
         }completion:^ (BOOL completed) {
          [centerProfileView removeFromSuperview];
          centerProfileView = rightProfileView;
         }];
         }else{
          [UIView animateWithDuration:0.2 delay:0.0 options:
          UIViewAnimationOptionTransitionNone animations:^{
          centerProfileView.frame=CGRectMake(0 , self.view.frame.origin.y,screenWidth,screenHeight);
          rightProfileView.frame=CGRectMake(screenWidth, self.view.frame.origin.y,screenWidth,screenHeight);
          } completion:^ (BOOL completed) { 
          [rightProfileView removeFromSuperview];
          rightProfileView = nil;
          currentIndex--;
          }];
         }
          [rightProfileView setUserInteractionEnabled:YES];
          [self.view setUserInteractionEnabled:YES];
          break;
         default:
          NSLog(@"unhandled state for gesture=%@", gesture);
    }
    
}

Where To Go From Here?

You can download the completed project from here.

Note: If UI does not look good in iPhone 6 or 6 plus then use size classes, autolayout & @2x images to make it fit.

FOUND THIS USEFUL? SHARE IT

Leave a Reply

Your email address will not be published. Required fields are marked *