I have an iOS cocos2d (v2) game in the app store that I had not updated for years, but recently discovered a bug and needed to fix it. This required me to go through all the pain of getting the app to build on a modern version of XCode. After I got it all working and am ready to submit my patch to the app store, I realized there is now a ridiculously slow lag in time when my app actually detects that the user has touched and held in place on the screen.
When looking at the call stack, if I quickly tap the screen everything works great, and my breakpoint is hit quickly:
But if I touch and hold down on the screen, there is almost a one second delay before my break point is even hit, and the call stack looks like:
My question is, how do I turn off this behavior so that there are no delayed touches or calls to UIGestureEnvironmentSortAndSendDelayedTouches
? In other words, I need touching and holding on the screen to fire the event immediately, exactly the same as it does when tapping quickly.
UPDATE
Here is the full stack trace:
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000100e79ab0 mygame`-[CCGLView touchesBegan:withEvent:](self=0x0000000102029c40, _cmd="touchesBegan:withEvent:", touches=0x0000000282f373c0, event=0x0000000281d62e20) at CCGLView.m:331
frame #1: 0x00000001ca6aeaf0 UIKitCore`_UIGestureEnvironmentSortAndSendDelayedTouches + 4324
frame #2: 0x00000001ca6a97ec UIKitCore`_UIGestureEnvironmentUpdate + 1236
frame #3: 0x000000019d8896bc CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32
frame #4: 0x000000019d884350 CoreFoundation`__CFRunLoopDoObservers + 412
frame #5: 0x000000019d8848f0 CoreFoundation`__CFRunLoopRun + 1264
frame #6: 0x000000019d8840e0 CoreFoundation`CFRunLoopRunSpecific + 436
frame #7: 0x000000019fafd584 GraphicsServices`GSEventRunModal + 100
* frame #8: 0x00000001caa98c00 UIKitCore`UIApplicationMain + 212
frame #9: 0x0000000100c7f8a4 mygame`main(argc=1, argv=0x000000016f2c77d8) at main.m:5
frame #10: 0x000000019d342bb4 libdyld.dylib`start + 4
Turns out the best way I could solve this was to set the window's UIGestureRecognizer instance's delegate:
# in app delegate:
CGRect frame = [[UIScreen mainScreen] bounds];
UIWindow *window = [[UIWindow alloc] initWithFrame:frame];
for (UIGestureRecognizer *gestureRecognizer in [window gestureRecognizers]) {
gestureRecognizer.delegate = self;
}
and then implement the following methods on that delegate:
-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
return NO;
}
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
return NO;
}
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceivePress:(UIPress *)press {
return NO;
}