1

난 그냥이 구현 :UIPanGestureRecognizer는 주로 수직 팬만 감지합니다. 실제로 수직 팬만 감지하도록하려면 어떻게해야합니까?

(. here를 설명한 것처럼)하지만

- (BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)panGestureRecognizer { 
    CGPoint translation = [panGestureRecognizer translationInView:someView]; 
    return fabs(translation.y) > fabs(translation.x); 
} 

사용자 팬이 수직으로 바로 대각선에 그것을 시작됩니다. 수직을 고려한 것에 대해 허용 오차를 훨씬 더 엄격하게 만드는 방법은 무엇입니까?

기본적으로 아래 이미지는 내가 수행 한 작업을 설명합니다. 첫 번째 다이어그램은 현재 감지하고있는 영역이며, 그 영역 내의 모든 것입니다. 두 번째 다이어그램은 내가 원하는 작업입니다. 순수한 수직 제스처를 감지

enter image description here

답변

1

, 그 translation.x == 0 다음 가정합니다.

참조한 게시물의 정답을 확인해야합니다. 그는 이전 위치를 현재 위치와 비교합니다. 당신은 감수성을 창조 할 수 있습니다. 내 project을 확인할 수 있습니다. 예를 들어,이 감각력을 사용하여 정의 할 때, 동작이 유효 할 때 (감각보다 작거나 같을 때) 또는 유효하지 않은 경우 (감수성보다 큼)를 확인할 수 있습니다. RPSliderViewController.m 안에있는 MOVEMENT_SENSIBILITY을 확인하십시오.

+0

이것은 멋지다. 정확히 내가 질문을 우연히 만났을 때 필요한 것. if : ((translation.x> 0) && (translation.x <40)) 또는 약간 비 완벽한 핑거 변환을 허용하기 위해 뭔가를 변경합니다. – topLayoutGuide

0

나는 그 목적을 위해 UIGestureRecognizer 하위 클래스를 작성했습니다. 그것은 수직 번역만을 추적합니다. 어쩌면 그것이 당신을 도울 것입니다. 다른 제스처 인식기로 사용할 수 있습니다. 임계 값을 설정하고 대상의 동작 방법에서 번역을 추적하기 만하면됩니다.

VerticalPanGestureRecognizer.h

#import <UIKit/UIKit.h> 
#import <UIKit/UIGestureRecognizerSubclass.h> 

@interface VerticalPanGestureRecognizer : UIGestureRecognizer 

@property (assign, nonatomic)float translation; 
@property (assign, nonatomic)float offsetThreshold; 

@end 

VerticalPanGestureRecognizer.m는

#import "VerticalPanGestureRecognizer.h" 

@interface VerticalPanGestureRecognizer() 
{ 
    CGPoint _startPoint; 
} 
@end 

@implementation VerticalPanGestureRecognizer 

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    if ([touches count] > 1) { 
     self.state = UIGestureRecognizerStateFailed; 
    } 
    else 
    { 
     _startPoint = [[touches anyObject] locationInView:self.view]; 
    } 
} 

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    if (self.state == UIGestureRecognizerStateFailed || self.state == UIGestureRecognizerStateCancelled) { 
     return; 
    } 
    CGPoint currentLocation = [[touches anyObject] locationInView:self.view]; 
    CGPoint translation; 
    translation.x = currentLocation.x - _startPoint.x; 
    translation.y = currentLocation.y - _startPoint.y;   

    if (self.state == UIGestureRecognizerStatePossible) 
    { 
     //if the x-translation is above our threshold the gesture fails 
     if (fabsf(translation.x) > self.offsetThreshold) 
      self.state = UIGestureRecognizerStateFailed; 
     //if the y-translation has reached the threshold the gesture is recognized and the we start sending action methods 
     else if (fabsf(translation.y) > self.offsetThreshold) 
      self.state = UIGestureRecognizerStateBegan; 

     return;     
    }   
    //if we reached this point the gesture was succesfully recognized so we now enter changed state 
    self.state = UIGestureRecognizerStateChanged; 

    //we are just insterested in the vertical translation 
    self.translation = translation.y; 
} 

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    //if at this point the state is still 'possible' the threshold wasn't reached at all so we fail 
    if (self.state == UIGestureRecognizerStatePossible) 
    { 
     self.state = UIGestureRecognizerStateFailed; 
    } 
    else 
    { 
     CGPoint currentLocation = [[touches anyObject] locationInView:self.view]; 
     CGPoint translation; 
     translation.x = _startPoint.x - currentLocation.x; 
     translation.y = _startPoint.y - currentLocation.y; 
     self.translation = translation.y; 
     self.state = UIGestureRecognizerStateEnded; 
    } 

} 

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    self.state = UIGestureRecognizerStateCancelled; 
} 

- (void)reset 
{ 
    [super reset]; 
    _startPoint = CGPointZero; 
} 

@end 
3

당신은 수직에서 각도를 계산하는 atan2f 주어진 xy 값을 사용할 수 있습니다. 예를 들어 각도가 수직에서 4도 미만인 경우 제스처를 시작하려면 다음과 같이 할 수 있습니다.

- (BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gesture { 
    CGPoint translation = [gesture translationInView:gesture.view]; 
    if (translation.x != 0 || translation.y != 0) { 
     CGFloat angle = atan2f(fabs(translation.x), fabs(translation.y)); 
     return angle < (4.0 * M_PI/180.0); // four degrees, but in radians 
    } 
    return FALSE; 
}