Search code examples
objective-cuiwebviewswipeuiswipegesturerecognizer

Swipeable controls in UIWebView


In my application, I have a file viewer that displays multiple types of content (images, pdf, text, etc) in a UIWebView.

I have swipe controls for flipping to the next page, and these generally work fine as long as the image is smaller than the webview and no scrolling is needed. Here is the code for that:

UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self  action:@selector(swipeRightAction:)];
swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
swipeRight.delegate = self;
[webView addGestureRecognizer:swipeRight];

However, if the an image is too large, the swipe controls no longer work. I have read a few other questions, where people have tried similar things but with no success.

I have seen seen suggestions for subclassing UIWebView, but haven't had any luck with this approach either.

Is there a way to add swipe controls to a UIWebView that will work consistently?


Solution

  • For my case, I ultimately did manage to get this working subclassing UIWebView. I also created a new delegate that is called when the directions swipes are performed.

    This may not be the best solution, but it is simple, reusable, and works.

    Here is some of the basic code:

    @interface SwipableWebView : UIWebView <UIGestureRecognizerDelegate>{
       id swipeableWebViewDelegate;
    }
    @property (nonatomic, retain) id <SwipableWebViewDelegate> swipeableWebViewDelegate;
    @end
    
    
    @implementation SwipableWebView{
    
    }
    
    @synthesize swipeableWebViewDelegate;
    
    - (id)initWithCoder:(NSCoder *)aDecoder{
      self = [super initWithCoder:aDecoder];
      if (self) {
          UISwipeGestureRecognizer  * swipeRight = [[UISwipeGestureRecognizer     alloc]initWithTarget:self action:@selector(swipeRight:)];
        swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
        [self addGestureRecognizer:swipeRight];
        swipeRight.delegate = self;
    
        UISwipeGestureRecognizer  * swipeLeft = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeLeft:)];
        swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
        [self addGestureRecognizer:swipeLeft];
        swipeLeft.delegate = self;
    
    
        UISwipeGestureRecognizer  * swipUp = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeUp:)];
        swipUp.direction = UISwipeGestureRecognizerDirectionUp;
        [self addGestureRecognizer:swipUp];
        swipUp.delegate = self;
    
        UISwipeGestureRecognizer  * swipeDown = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeDown:)];
        swipeDown.direction = UISwipeGestureRecognizerDirectionDown;
        [self addGestureRecognizer:swipeDown];
        swipeDown.delegate = self;
      }
      return self;
    }
    
    
    
    -(void)swipeLeft:(id)swipe{
      [swipeableWebViewDelegate webViewSwipeLeft:swipe];
    }
    
    -(void)swipeRight:(id)swipe{
      [swipeableWebViewDelegate webViewSwipeRight:swipe];
    }
    
    -(void)swipeUp:(id)swipe{
      [swipeableWebViewDelegate webViewSwipeUp:swipe];
    }
    
    -(void)swipeDown:(id)swipe{
      [swipeableWebViewDelegate webViewSwipeDown:swipe];
    }
    
     - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
        return YES;
    }
    
    @end
    
    
    
    @protocol SwipableWebViewDelegate <NSObject>
     -(void)webViewSwipeLeft:(id)swipe;
     -(void)webViewSwipeRight:(id)swipe;
     -(void)webViewSwipeUp:(id)swipe;
     -(void)webViewSwipeDown:(id)swipe;
    @end