有没有办法加快它,或者只是为了确定是否是轻击的手势处理是密集的并且不可能缩短?
延迟似乎取决于处理手势需要多长时间,所以是的,无法调整它(您可以登录-touchesBegan:withEvent: 以查看它被调用的确切时间)。例如,如果您用UITapGestureRecognizer 触摸UIView 并且不移动手指,点击识别器仍然认为您有可能在相同位置抬起手指,这将被识别为点击。所以它会一直等到你平移手指或抬起它。另一方面,如果您立即平移,则 UIView 几乎不会延迟发送到-touchesBegan:withEvent:。
您可以尝试的解决方法是:
请改用手势识别器的 cancelTouchesInView 属性。如果您将其设置为YES,则UIView 将立即处理触摸,然后如果手势识别器最终将触摸识别为手势,则会发送视图-touchesCancelled:withEvent:,您可以在其中回滚您所做的任何更改制作。
在UIView 中使用cancelTouchesInView 和NSTimer。在UIView 的-touchesBegan:withEvent: 中启动NSTimer,当它触发时,对视图执行您的操作。如果视图在定时器触发之前被发送到-touchesCancelled:withEvent:,请取消定时器。
子类UIGestureRecognizer 并实现您自己的点击识别器:)
我制作了选项 1 和 2 的示例。该示例有一个可以在屏幕上拖动的视图,并且该视图有一个可以更改视图颜色的点击识别器。如果您点击视图但在释放之前稍微拖动它,您会看到“回滚”将视图捕捉到触摸之前的位置。如果将JCPanningView 的delayResponseToTouch 设置为YES,则在延迟期内看不到任何拖动。
这可能对您有用,也可能对您无效,具体取决于您的 UIViews 处理他们的触摸的方式。
这是视图控制器的界面 (JCGestureViewController.h):
#import <UIKit/UIKit.h>
@interface JCGestureViewController : UIViewController
@end
@interface JCPanningView : UIView
@property (nonatomic) BOOL delayResponseToTouch;
- (void)changeColor;
@end
和实施(JCGestureViewController.m):
#import "JCGestureViewController.h"
@interface JCGestureViewController ()
@property (strong, nonatomic) JCPanningView *panningView;
@end
@implementation JCGestureViewController
- (void)viewDidLoad
{
[super viewDidLoad];
_panningView = [[JCPanningView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 200.0f, 200.0f)];
[self.view addSubview:_panningView];
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(tappedPanningView)];
tapRecognizer.cancelsTouchesInView = YES;
[_panningView addGestureRecognizer:tapRecognizer];
// set this to YES to have a timer delay the view's response to touches
_panningView.delayResponseToTouch = NO;
}
- (void)tappedPanningView
{
[self.panningView changeColor];
}
@end
@interface JCPanningView ()
@property (nonatomic) CGPoint touchBeganLocation;
@property (nonatomic) CGPoint centerWhenTouchBegan;
@property (nonatomic) BOOL respondToTouches;
@property (nonatomic) NSTimer *timer;
@end
@implementation JCPanningView
- (void)dealloc
{
if (_timer) {
[_timer invalidate];
_timer = nil;
}
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [self randomColor];
}
return self;
}
- (void)changeColor
{
self.backgroundColor = [self randomColor];
}
- (CGFloat)randomRGBValue
{
return (arc4random() % 255) / 255.0f;
}
- (UIColor *)randomColor
{
return [UIColor colorWithRed:[self randomRGBValue] green:[self randomRGBValue] blue:[self randomRGBValue] alpha:1.0f];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"touchesBegan:");
[super touchesBegan:touches withEvent:event];
UITouch *touch = [touches anyObject];
self.touchBeganLocation = [touch locationInView:self.superview];
self.centerWhenTouchBegan = self.center;
if (self.delayResponseToTouch) {
if (self.timer) {
[self.timer invalidate];
}
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.2
target:self
selector:@selector(startRespondingToTouches)
userInfo:nil
repeats:NO];
}
}
- (void)startRespondingToTouches
{
self.respondToTouches = YES;
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
self.center = self.centerWhenTouchBegan;
if (self.timer) {
[self.timer invalidate];
self.timer = nil;
}
if (self.delayResponseToTouch) {
self.respondToTouches = NO;
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesMoved:touches withEvent:event];
if (self.delayResponseToTouch && !self.respondToTouches) {
return;
}
UITouch *touch = [touches anyObject];
CGPoint newLocation = [touch locationInView:self.superview];
CGPoint delta = CGPointMake(newLocation.x - self.touchBeganLocation.x, newLocation.y - self.touchBeganLocation.y);
self.center = CGPointMake(self.centerWhenTouchBegan.x + delta.x, self.centerWhenTouchBegan.y + delta.y);
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
if (self.delayResponseToTouch) {
self.respondToTouches = NO;
}
}
@end