Марк, я столкнулся с той же ошибкой.Если вы опубликуете свой радар #, я буду дублировать его в bugreporter.
Я написал следующий обходной путь.Я создаю подкласс UITapGestureRecognizer, затем использую подкласс для отслеживания касаний, которые вызвали действие жеста.Если мы получим те же штрихи в штрихах, закругленных на виде, мы перенаправим на штрихи Отменено.'немедленная цель' необходима, потому что вызов touchesEnded в представлении происходит после прикосновения жеста, но до вызова действия жеста.
RPTapGestureRecognizer.h:
#import <UIKit/UIKit.h>
#import <UIKit/UIGestureRecognizerSubclass.h>
@interface RPTapGestureRecognizer : UITapGestureRecognizer
@property (nonatomic, retain) NSSet *lastTouches;
- (void)setImmediateTarget:(id)inTarget action:(SEL)inAction;
@end
RPTapGestureRecognizer.m:
#import "RPTapGestureRecognizer.h"
@interface RPTapGestureRecognizer ()
@property (nonatomic) SEL immediateAction;
@property (nonatomic, assign) id immediateTarget;
@end
@implementation RPTapGestureRecognizer
@synthesize lastTouches;
@synthesize immediateAction, immediateTarget;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
self.lastTouches = nil;
[super touchesBegan:touches withEvent:event];
}
- (void)setImmediateTarget:(id)inTarget action:(SEL)inAction
{
self.immediateTarget = inTarget;
self.immediateAction = inAction;
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UIGestureRecognizerState startingState, finalState;
startingState = self.state;
[super touchesEnded:touches withEvent:event];
finalState = self.state;
if (startingState != finalState &&
finalState == UIGestureRecognizerStateEnded) {
/* Must copy; the underlying NSCFSet will be modified by the superclass, removing the touches */
self.lastTouches = [[touches copy] autorelease];
if (self.immediateAction)
[self.immediateTarget performSelector:self.immediateAction
withObject:self];
}
}
- (void)dealloc
{
self.lastTouches = nil;
self.immediateTarget = nil;
[super dealloc];
}
@end
По виду:
@synthesize lastTapGesture
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
if (self.lastTapGesture && [self.lastTapGesture.lastTouches isEqualToSet:touches]) {
[self touchesCancelled:touches withEvent:event];
self.lastTapGesture = nil;
return;
}
/* touches ended implementation here */
}
- (void)willHandleMouseTapGesture:(RPTapGestureRecognizer *)tapGesture
{
/* Because one tap gesture is dependent upon another, the touchesEnded method is still going to be called, instead of touchesCanceled.
* This is an Apple bug against all versions of iOS at least up to 5.0. It will be called in the run loop before tapGesture's action is called.
*
* See /7973431/kak-otmenit-nazhatie-knopki-esli-uigesturerecognizer-srabatyvaet#7973465 for details.
*/
self.lastTapGesture = tapGesture;
}
- (void)configureGestures
{
/* Two finger taps */
RPTapGestureRecognizer *tapGestureOne;
tapGestureOne = [[[RPTapGestureRecognizer alloc] initWithTarget:self
action:@selector(handleMouseTapGesture:)] autorelease];
tapGestureOne.numberOfTapsRequired = 1;
tapGestureOne.numberOfTouchesRequired = 2;
[tapGestureOne setImmediateTarget:self action:@selector(willHandleMouseTapGesture:)];
[self addGestureRecognizer:tapGestureOne];
[myGestures addObject:tapGestureOne];
RPTapGestureRecognizer *tapGestureTwo;
tapGestureTwo = [[[RPTapGestureRecognizer alloc] initWithTarget:self
action:@selector(handleMouseTapGesture:)] autorelease];
tapGestureTwo.numberOfTapsRequired = 2;
tapGestureTwo.numberOfTouchesRequired = 2;
[tapGestureTwo setImmediateTarget:self action:@selector(willHandleMouseTapGesture:)];
[self addGestureRecognizer:tapGestureTwo];
}