有没有任何方法可以加快它,或者只是处理手势以确定它是否为轻拍的过程很复杂,不可能缩短?延迟似乎取决于处理手势所需的时间,因此无法调整它(您可以记录-touchesBegan:withEvent:以查看确切的调用时间)。例如,如果您使用UITapGestureRecognizer触摸UIView并且不移动手指,则轻拍识别器仍然认为您有机会在相同位置抬起手指,这将被识别为轻拍。因此,它将继续等待,直到您滑动手指或将其抬起。另一方面,如果立即平移,则UIView几乎没有延迟就会发送-touchesBegan:withEvent:。
您可以尝试的解决方法是:
1.改用手势识别器的cancelTouchesInView属性。如果将其设置为YES,则UIView将立即处理触摸,然后如果手势识别器最终将触摸识别为手势,则视图将发送-touchesCancelled:withEvent:,在其中可以回滚所做的任何更改。
2.在UIView中使用cancelTouchesInView和NSTimer。在UIView的-touchesBegan:withEvent:中启动NSTimer,当其触发时,在视图上执行操作。如果视图在计时器触发之前发送了-touchesCancelled:withEvent:,则取消计时器。
3.子类化UIGestureRecognizer并实现自己的轻拍识别器:)
我已经制作了选项1和2的示例。该示例具有可以在屏幕上拖动的视图,该视图具有更改视图颜色的轻拍识别器。如果您轻拍视图,但在释放之前稍微拖动它,则会看到“回滚”将视图捕捉到触摸前的位置。如果将JCPanningView的delayResponseToTouch设置为YES,则在延迟期内不会看到任何拖动。
这可能适用于您,具体取决于您的UIView如何处理其触摸。
以下是视图控制器的接口(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];
_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
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
)。 - EricLeaf