10

So all I wanna do is play a sound when the user touches a UIScrollView. The UIScrollViewDelegate has that scrollViewWillBeginDragging: method but it only gets called on touchMoved. I want it to get called on touchBegan.

Tried touchesBegan:withEvent: but it doesn't receive any touch. Anyone has a clue?

samvermette
  • 40,269
  • 27
  • 112
  • 144

8 Answers8

18

Use a Tap Gesture Recognizer instead:

UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(touch)];
[recognizer setNumberOfTapsRequired:1];
[recognizer setNumberOfTouchesRequired:1];
[scrollView addGestureRecognizer:recognizer];  

Or

make subClass of your UIScrollView and implement all

    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

// If not dragging, send event to next responder
  if (!self.dragging){ 
    [self.nextResponder touchesBegan: touches withEvent:event]; 
  }
  else{
    [super touchesEnded: touches withEvent: event];
  }
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{

// If not dragging, send event to next responder
    if (!self.dragging){ 
     [self.nextResponder touchesBegan: touches withEvent:event]; 
   }
   else{
     [super touchesEnded: touches withEvent: event];
   }
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{

  // If not dragging, send event to next responder
   if (!self.dragging){ 
     [self.nextResponder touchesBegan: touches withEvent:event]; 
   }
   else{
     [super touchesEnded: touches withEvent: event];
   }
}
Rajneesh071
  • 30,846
  • 15
  • 61
  • 74
13

Use a Tap Gesture Recognizer instead:

UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(touch)];
[recognizer setNumberOfTapsRequired:1];
[recognizer setNumberOfTouchesRequired:1];
[scrollView addGestureRecognizer:recognizer];
Adam Ivancza
  • 2,459
  • 1
  • 25
  • 36
  • Ok, this Works, but How should I Declare the Method "touch" to Receive the Place where the User Touched? – Hernan Arber Aug 05 '14 at 11:45
  • @HernanArber For example: http://stackoverflow.com/questions/8721864/getting-screen-coordinates-from-uilongpressgesturerecognizer – Adam Ivancza Aug 05 '14 at 12:36
6

I think you will have to subclass UIScrollView to be able to do this.

touchesBegan:withEvent: is only sent to subclasses of UIView. You are problably implementing touchesBegan:withEvent: in your controller, right? If so, it won't work from there...

Alternatively, if you put a subclass of UIView (that you wrote) in your UIScrollView, you can also catch the touchesBegan event from there (but only when the user touches that particular subview). UIScrollView passes on touches to its subviews by default (see touchesShouldBegin:withEvent:inContentView: in UIScrollView).

Zoran Simic
  • 10,293
  • 6
  • 33
  • 35
5

You can also respond to these events in your controller. For that to work, you have to define this feature (in your controller):

- (BOOL)canBecomeFirstResponder {
    return YES;
}

Then, in 'viewDidAppear', you need to call 'becomeFirstResponder':

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [self becomeFirstResponder];
1

New updates on the issue here (including a link to ZoomScrollView source code + some excellent explanation on UIScrollView internals) . Also, check out Apple's updated ScrollViewSuite example.

Community
  • 1
  • 1
DenTheMan
  • 1,277
  • 2
  • 13
  • 21
0

You should add touchesBegan:withEvent: on your UIScrollView, not on the UIScrollViewDelegate. UIScrollView is a sub class of UIResponder, which has the touch events.

nash
  • 2,181
  • 15
  • 16
0

Rajneesh071 answer in swift 4 Change the custom class of scrollView in storyboard to CustomScrollView

import Foundation

class CustomScrollView: UIScrollView {
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        if !isDragging {
            next?.touchesBegan(touches, with: event)
        } else {
        super.touchesBegan(touches, with: event)
        }
    }
}
abhimuralidharan
  • 5,752
  • 5
  • 46
  • 70
0

You need to subclass scroll view and then implement the touchesBegan method.You need also set the delayTouchDown property to false.

Tibin Thomas
  • 1,365
  • 2
  • 16
  • 25