2

I have a main UIView, which contains a scrollview. I have set up UIGestureRecognizer for the main view for 4 types of swipes using this code:

UISwipeGestureRecognizer *swipeUpRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(upCommand)];
[swipeUpRecognizer setDirection:(UISwipeGestureRecognizerDirectionUp)];
[mainGameView addGestureRecognizer:swipeUpRecognizer];
... // Done 4 times for each direction

When I disable scrolling on the scrollview, this code works great (I can swipe anywhere on the screen and the associated actions perform as expected). However, I want to add functionality so that if I touch two fingers on the scrollview, I can pan back and forth as a scrollview usually functions. I tried adding a gesture recognizer to the scrollview to detect when two fingers pan:

- (void)viewDidLoad
{
    UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(recognizePan)];
    panGestureRecognizer.minimumNumberOfTouches = 2;
    panGestureRecognizer.maximumNumberOfTouches = 2;
    [scrollView addGestureRecognizer:panGestureRecognizer];
}

- (void)recognizePan
{
    [gameScrollView setScrollEnabled:YES];
}

I used this in conjunction with the following method to disable scrolling again once the fingers are lifted:

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    [gameScrollView setScrollEnabled:NO];
}

This kind of worked, but not in the way I want it to. When I drag two fingers on the scrollview, scrolling would be set to enabled, but I can't use those two fingers to scroll. I first need to lift the two fingers and then I am able to scroll with one finger (two fingers don't work). And when I lift up the single finger that could scroll through the scrollview, scrolling is disabled, as set in scrollViewDidEndDragging.

Obviously, this type of scrolling would not be very user-friendly, but I can't seem to find a way to set the scrollview so it only scrolls when two fingers are dragging on the scrollview. Thanks for any help in advance.

~ 17-year-old amateur iOS developer & new to gestures

EDIT: As per one of the suggestions from this question, I have tried implementing a subclass of UISubView to override the default touchesBegan method, but I haven't been able to get it to work.

CustomScrollView.h:

@interface CustomScrollView : UIScrollView 
{
}

@end

CustomScrollView.m:

#import "CustomScrollView.h"

@implementation CustomScrollView

- (id)initWithFrame:(CGRect)frame 
{
  return [super initWithFrame:frame];
}

- (void) touchesBegan: (NSSet *) touches withEvent: (UIEvent *) event 
{   
  // What goes here so that The action it can be called from the ViewController.h
}

@end

ViewController.h:

#import <UIKit/UIKit.h>

@class CustomScrollView;

@interface ViewController : UIViewController <UIScrollViewDelegate>
{
  CustomScrollView *scrollView;
}

@end

ViewController.m:

- (void) touchesEnded: (NSSet *) touches withEvent: (UIEvent *) event 
{
  // What goes here?
}
Community
  • 1
  • 1
iMinichrispy
  • 134
  • 2
  • 14

4 Answers4

2

Subclass The ScrollView and implement following Method:

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
  if(gestureRecognizer.numberOfTouches != 2) {
    return NO;
  } else {
    return YES;
  }
}
Seraj Ahmad
  • 405
  • 6
  • 10
0

Try to subclass UIScrollView and override the method touchesShouldBegin:withEvent:inContentView:. The documentation states the following:

Overridden by subclasses to customize the default behavior when a finger touches down in displayed content.

- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view

So you may be able to check if you have more than one touch and only with that return a true value.

Fábio Oliveira
  • 2,346
  • 21
  • 30
0

I think starting point to tackle this problem is following UIView method:

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer

When this method is called we could check touch position, number of touch, etc., then decide which recognizer to use. If you make a UIScrollView subclass and override gestureRecognizerShouldBegin, you could control the UIScrollView's default gesture recognizer (pan/zoom) also.

Of course, don't need to use the scrollEnabled property.

9dan
  • 4,222
  • 2
  • 29
  • 44
-1

try this

  - (void)viewDidLoad
{  

    [super viewDidLoad];


    UISwipeGestureRecognizer *swipeUpRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(upCommand)];
    swipeUpRecognizer.delegate = self;
    [swipeUpRecognizer setDirection:(UISwipeGestureRecognizerDirectionUp)];
    [self.view addGestureRecognizer:swipeUpRecognizer];
    scrollView.delegate = scrollView;

    panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(recognizePan:)];
    panGestureRecognizer.minimumNumberOfTouches = 1;
    panGestureRecognizer.maximumNumberOfTouches = 1;
    [self.scrollView addGestureRecognizer:panGestureRecognizer];

}
-(void)upCommand
{
    NSLog(@"up");    
}
-(void)viewDidAppear:(BOOL)animated
{
    scrollView.contentSize = CGSizeMake(320, 600);
}
- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)recognizePan:(UIGestureRecognizer*)recognizer
{
    NSLog(@"pan");//Does nothing but catches the pan of scrollview so it doesnt scroll


}
//simultan recognition of pan and gesture
- (BOOL) gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES;
}

the panrecognicer catches the one-finger swipe in Scrollview, so the view doesn't scroll, then adding the

shouldRecognizeSimultaneouslyWithGestureRecognizer

makes that both, pan and gesture, will be catched.

thats all

edit you have to add

<UIGestureRecognizerDelegate>

to your .h file

Starbax
  • 1,005
  • 2
  • 12
  • 32