dan*_*anh 4 uigesturerecognizer ios
我有一个观点,我已经添加了泛和长按UIGestureRecognizer.平底锅用于移动视图.我想做的是注意触摸已停止移动(同时保持活动状态)并触发长按.
我发现在平底锅开始后从未触发长按.我已经尝试设置委托并实现:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
NSLog(@"simultaneous %@", gestureRecognizer.class);
return YES;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
NSLog(@"require fail %@", gestureRecognizer.class);
return [gestureRecognizer isKindOfClass:[UIPanGestureRecognizer self]];
// also tried return YES;
// also tried return [gestureRecognizer isKindOfClass:[UILongPressGestureRecognizer self]];
}
Run Code Online (Sandbox Code Playgroud)
我试过愚弄pan gr的allowableMovement,也无济于事.我只是放弃并在pan gr中使用一个计时器,它被取消,然后重置动作,但我希望SDK能为我做状态机的东西.
如果其他人需要它,这里的代码对我有用.目标是使视图对长按和平移敏感,包括不按平底锅的长按,反之亦然.
// setup
@property (strong,nonatomic) NSTimer *timer; // triggers the long press during pan
@property (strong,nonatomic) UIView *longPressView; // need this to track long press state
// view is the view we're interested in panning and long pressing
UIPanGestureRecognizer *panGR = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGR:)];
[view addGestureRecognizer:panGR];
// this starts a long press when no pan has occurred
UILongPressGestureRecognizer *longGR = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressGR:)];
[view addGestureRecognizer:longGR];
Run Code Online (Sandbox Code Playgroud)
当平底锅开始或更改时,启动计时器.如果计时器在平移结束之前到期(触摸释放),那么我们需要长按.
- (void)panGR:(UIPanGestureRecognizer *)gr {
if (gr.state == UIGestureRecognizerStateBegan) {
[self startTimer:gr.view];
} else if (gr.state == UIGestureRecognizerStateChanged) {
[self startTimer:gr.view];
// do whatever you want to do with pan state in this method
// in my case, I'm translating the view here
} else if (gr.state == UIGestureRecognizerStateEnded) {
if (self.longPressView) {
[self longPressEnded];
} else {
[self.timer invalidate];
}
}
}
Run Code Online (Sandbox Code Playgroud)
我们给视图的计时器用户信息.您可能需要存储手势状态的其他部分,如位置等.使用用户信息字典以相同的方式.
- (void)startTimer:(UIView *)view {
if (self.longPressView) return;
[self.timer invalidate];
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.8 target:self
selector:@selector(longPressTimer:)
userInfo:@{ @"view": view} repeats:NO];
}
-(void)longPressTimer:(NSTimer *)timer {
self.longPressView = timer.userInfo[@"view"];
[self longPressBegan];
}
Run Code Online (Sandbox Code Playgroud)
由于timer方法没有关联的gr,因此将我们通常放在gr处理程序中的所有逻辑分解出来,这样定时器处理程序和gr处理程序就可以调用它.
- (void)longPressGR:(UILongPressGestureRecognizer *)gr {
if (gr.state == UIGestureRecognizerStateBegan) {
self.longPressView = gr.view;
[self longPressBegan];
} else if (gr.state == UIGestureRecognizerStateEnded) {
[self longPressEnded];
}
}
- (void)longPressBegan {
NSLog(@"long press began");
}
- (void)longPressEnded {
self.longPressView = nil;
NSLog(@"long press ended");
}
Run Code Online (Sandbox Code Playgroud)