Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIButton touch down action not called when touch down but called when touch moved

Hi need to perform an action when user touched DOWN the UIButton

[button addTarget:self action:@selector(touchDown:event:) forControlEvents:UIControlEventTouchDown];
[button addTarget:self action:@selector(drag:event:) forControlEvents:UIControlEventTouchDragInside];
[button addTarget:self action:@selector(drag:event:) forControlEvents:UIControlEventTouchDragOutside];
[button addTarget:self action:@selector(touchUp:event:) forControlEvents:UIControlEventTouchUpInside];
[button addTarget:self action:@selector(touchUp:event:) forControlEvents:UIControlEventTouchUpOutside];

- (void)touchDown:(UIButton *)sender event:(UIEvent *)event {
    //begin only called when I move my finger 
}


- (void)drag:(UIButton *)sender event:(UIEvent *)event {
    //called when I move my finger, after touchDown was called
}
- (void)touchUp:(UIButton *)sender event:(UIEvent *)event {

}

The root view controller of my app is tabbarviewcontroller, and each tab is a navigation view controller. in the viewWillAppear method of the chatting scene I hide the tab bar.

the result is, on device, when i touch down, it's not called, and when I move my finger a bit, it is called.

Note:

  1. using Long Press gesture recognizer does not work either.

  2. If I put the button away from tab bar area, it works on device.

  3. on simulator, everything is fine.

I created a sample project: https://drive.google.com/folderview?id=0B_9_90avvmZtRmRDeHFkbFJLaFk&usp=sharing

like image 232
OMGPOP Avatar asked Mar 09 '14 17:03

OMGPOP


2 Answers

Is this button anywhere inside a scrollview (including collection or tableview)? If so, then that's exactly the expected behavior. The system waits to see if you're going to tap the button or drag the scrollview. From Apple:

Because a scroll view has no scroll bars, it must know whether a touch signals an intent to scroll versus an intent to track a subview in the content. To make this determination, it temporarily intercepts a touch-down event by starting a timer and, before the timer fires, seeing if the touching finger makes any movement. If the timer fires without a significant change in position, the scroll view sends tracking events to the touched subview of the content view. If the user then drags their finger far enough before the timer elapses, the scroll view cancels any tracking in the subview and performs the scrolling itself. Subclasses can override the touchesShouldBegin:withEvent:inContentView:, pagingEnabled, and touchesShouldCancelInContentView: methods (which are called by the scroll view) to affect how the scroll view handles scrolling gestures.

If you don't want this behavior, you can set parentview.delaysContentTouches to NO You may also need to set canCancelContentTouches to NO

like image 66
mackworth Avatar answered Sep 22 '22 11:09

mackworth


Hi @OMGPOP I have the same problem with you, Now I has resolved it add below code:

self.navigationController.interactivePopGestureRecognizer.delaysTouchesBegan = NO;

I'm sure it's your savior, because I has download your sample code and add above code, It's work fine. like this:

self.navigationController.interactivePopGestureRecognizer.delaysTouchesBegan = NO;


[self.holdToRecordButton addTarget:self action:@selector(touchDown:event:) forControlEvents:UIControlEventTouchDown];
[self.holdToRecordButton addTarget:self action:@selector(drag:event:) forControlEvents:UIControlEventTouchDragInside];
[self.holdToRecordButton addTarget:self action:@selector(drag:event:) forControlEvents:UIControlEventTouchDragOutside];
[self.holdToRecordButton addTarget:self action:@selector(touchUp:event:) forControlEvents:UIControlEventTouchUpInside];
[self.holdToRecordButton addTarget:self action:@selector(touchUp:event:) forControlEvents:UIControlEventTouchUpOutside];
like image 45
jhondge Avatar answered Sep 20 '22 11:09

jhondge