UIPanGestureRecognizer - 仅垂直或水平 [英] UIPanGestureRecognizer - Only vertical or horizontal
问题描述
我有一个视图,它有一个 UIPanGestureRecognizer
来垂直拖动视图。所以在识别器回调中,我只更新y坐标来移动它。这个视图的超级视图有一个 UIPanGestureRecognizer
,它将水平拖动视图,只是更新x坐标。
I have a view that has a UIPanGestureRecognizer
to drag the view vertically. So in the recognizer callback, I only update the y-coordinate to move it. The superview of this view, has a UIPanGestureRecognizer
that will drag the view horizontally, just updating the x-coordinate.
问题是第一个 UIPanGestureRecognizer
正在使用该事件垂直移动视图,因此我无法使用超视图手势。
The problem is that the first UIPanGestureRecognizer
is taking the event to move the view vertically, so I can not use the superview gesture.
我试过
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldRecognizeSimultaneouslyWithGestureRecognizer:
(UIGestureRecognizer *)otherGestureRecognizer;
两者都有效,但我不希望这样。我希望只有在运动明显水平的情况下才能检测水平。因此,如果 UIPanGestureRecognizer
具有direction属性,那就太棒了。
and both will work, but I don't want that. I want the horizontally to be detected only if the movement is clearly horizontal. So it would be great if the UIPanGestureRecognizer
had a direction property.
如何实现此行为?我发现这些文档非常令人困惑,所以也许有人可以在这里更好地解释它。
How can I achieve this behavior? I find the docs very confusing, so maybe someone can explain it better here.
推荐答案
我想出了创建UIPanGestureRecognizer的子类
I figured it out creating a subclass of UIPanGestureRecognizer
DirectionPanGestureRecognizer:
DirectionPanGestureRecognizer:
#import <Foundation/Foundation.h>
#import <UIKit/UIGestureRecognizerSubclass.h>
typedef enum {
DirectionPangestureRecognizerVertical,
DirectionPanGestureRecognizerHorizontal
} DirectionPangestureRecognizerDirection;
@interface DirectionPanGestureRecognizer : UIPanGestureRecognizer {
BOOL _drag;
int _moveX;
int _moveY;
DirectionPangestureRecognizerDirection _direction;
}
@property (nonatomic, assign) DirectionPangestureRecognizerDirection direction;
@end
DirectionPanGestureRecognizer.m:
DirectionPanGestureRecognizer.m:
#import "DirectionPanGestureRecognizer.h"
int const static kDirectionPanThreshold = 5;
@implementation DirectionPanGestureRecognizer
@synthesize direction = _direction;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesMoved:touches withEvent:event];
if (self.state == UIGestureRecognizerStateFailed) return;
CGPoint nowPoint = [[touches anyObject] locationInView:self.view];
CGPoint prevPoint = [[touches anyObject] previousLocationInView:self.view];
_moveX += prevPoint.x - nowPoint.x;
_moveY += prevPoint.y - nowPoint.y;
if (!_drag) {
if (abs(_moveX) > kDirectionPanThreshold) {
if (_direction == DirectionPangestureRecognizerVertical) {
self.state = UIGestureRecognizerStateFailed;
}else {
_drag = YES;
}
}else if (abs(_moveY) > kDirectionPanThreshold) {
if (_direction == DirectionPanGestureRecognizerHorizontal) {
self.state = UIGestureRecognizerStateFailed;
}else {
_drag = YES;
}
}
}
}
- (void)reset {
[super reset];
_drag = NO;
_moveX = 0;
_moveY = 0;
}
@end
这只会触发手势如果用户开始拖动所选行为。将direction属性设置为正确的值,您就可以设置。
This will only trigger the gesture if the user starts dragging in the selected behavior. Set the direction property to a correct value and you are all set.
这篇关于UIPanGestureRecognizer - 仅垂直或水平的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!