UISwipeGestureRecognizer의 방향 설정


132

뷰 기반 iPhone 프로젝트에 간단한 스 와이프 제스처 인식을 추가하고 싶습니다. 모든 방향 (오른쪽, 아래쪽, 왼쪽, 위쪽)의 제스처를 인식해야합니다.

UISwipeGestureRecognizer에 대한 문서에 명시되어 있습니다.

비트 OR 피연산자를 사용하여 여러 UISwipeGestureRecognizerDirection 상수를 지정하여 여러 방향을 지정할 수 있습니다. 기본 방향은 UISwipeGestureRecognizerDirectionRight입니다.

그러나 나를 위해 작동하지 않습니다. 네 방향이 모두 OR이면 왼쪽 및 오른쪽 스 와이프 만 인식됩니다.

- (void)viewDidLoad {
    UISwipeGestureRecognizer *recognizer;

    recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeFrom:)];
    [recognizer setDirection:(UISwipeGestureRecognizerDirectionRight | UISwipeGestureRecognizerDirectionDown | UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionUp)];
    [[self view] addGestureRecognizer:recognizer];
    [recognizer release]; 
    [super viewDidLoad];
}

-(void)handleSwipeFrom:(UISwipeGestureRecognizer *)recognizer {
    NSLog(@"Swipe received.");
}

뷰에 4 명의 인식자를 추가 하여이 문제를 해결했지만 왜 문서에서 광고 된대로 작동하지 않는지 궁금합니다.

- (void)viewDidLoad {
    UISwipeGestureRecognizer *recognizer;

    recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeFrom:)];
    [recognizer setDirection:(UISwipeGestureRecognizerDirectionRight)];
    [[self view] addGestureRecognizer:recognizer];
    [recognizer release];

    recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeFrom:)];
    [recognizer setDirection:(UISwipeGestureRecognizerDirectionUp)];
    [[self view] addGestureRecognizer:recognizer];
    [recognizer release];

    recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeFrom:)];
    [recognizer setDirection:(UISwipeGestureRecognizerDirectionDown)];
    [[self view] addGestureRecognizer:recognizer];
    [recognizer release];

    recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeFrom:)];
    [recognizer setDirection:(UISwipeGestureRecognizerDirectionLeft)];
    [[self view] addGestureRecognizer:recognizer];
    [recognizer release];

    [super viewDidLoad];
}

-(void)handleSwipeFrom:(UISwipeGestureRecognizer *)recognizer {
    NSLog(@"Swipe received.");
}

3
전적으로 관련이 없지만 [super viewDidLoad]; (무효) viewDidLoad에 -에서 첫 번째 문이어야한다
미 히어 메타

답변:


115

버그가있는 것 같습니다. 허용 된 방향을 지정할 수 있습니다. 그러나 액션 선택기 메서드에서 스 와이프를 트리거 한 실제 방향 에 액세스하려고 하면 원래 설정 한 비트 마스크가 여전히 허용됩니다.

즉, 둘 이상의 방향이 허용되면 실제 방향 확인이 항상 실패합니다. 선택기 방법 (예 :)에서 'direction'값을 출력 할 때 쉽게 확인할 수 있습니다 -(void)scrollViewSwiped:(UISwipeGestureRecognizer *)recognizer.

버그 보고서 (# 8276386)를 Apple에 제출했습니다.

[업데이트] Apple에서 의도 한대로 동작한다는 응답을 받았습니다.

예를 들어 테이블보기에서는 테이블보기 셀에서 왼쪽이나 오른쪽으로 스 와이프하여 '삭제'를 트리거 할 수 있습니다 (스 와이프 동작의 방향이 왼쪽과 오른쪽으로 설정 됨)

이는 원래 해결 방법이 사용되는 방식임을 의미합니다. 방향 속성은 제스처를 올바르게 인식하는 데만 사용할 수 있지만 인식을 트리거 한 실제 방향과 비교하기 위해 성공적인 인식에서 수행 된 방법에서는 수행되지 않습니다.


35
스 와이프 제스처 인식기를 처음 사용하는 거의 모든 사람이 방향 속성이 어떻게 작동해야하는지에 대해 똑같은 잘못된 가정을한다고 생각합니다.
memmons

위, 아래, 왼쪽 및 오른쪽 스 와이프를 추적하려면 서로 다른 4 개의 인식기를 만들어야하는 것은 어리석은 일입니다.
memmons

와우 좀 짜증나지만, 큰 거래는 아니지만 그들이 추가 할 수있는 것처럼 보인다
marchinram

2
헤더 파일은 다음과 같습니다. @property (nonatomic) UISwipeGestureRecognizerDirection direction; // 기본값은 UISwipeGestureRecognizerDirectionRight입니다. 원하는 스 와이프 방향. 여러 방향을 지정할 수 있습니다
nicktmro

1
이것은 애플 측에서 이상한 구현처럼 보인다고 동의했다. 여러 방향을 지정한 다음 해당 방향 중 하나를 테스트 할 수 있어야합니다.
ChrisP

25

왼쪽 / 오른쪽 및 위쪽 / 아래쪽 제스처는 쌍으로 함께 작동하므로 두 개의 제스처 인식기 만 지정하면됩니다. 그리고 문서는 잘못된 것 같습니다.


이것이 올바른 해결책입니다. 2 개의 GR, 하나는 위아래로, 하나는 왼쪽과 오른쪽으로. 빙고!
logancautrell

22

글쎄, Lars와 같은 2 가지 제스처를 추가하여 문제를 해결했으며 완벽하게 작동했습니다 ...

1) 왼쪽 / 오른쪽 2) 위 / 아래

  

UISwipeGestureRecognizer *swipeLeftRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
    [swipeLeftRight setDirection:(UISwipeGestureRecognizerDirectionRight | UISwipeGestureRecognizerDirectionLeft )];
    [self.view addGestureRecognizer:swipeLeftRight];

    UISwipeGestureRecognizer *swipeUpDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
    [swipeUpDown setDirection:(UISwipeGestureRecognizerDirectionUp | UISwipeGestureRecognizerDirectionDown )];
    [self.view addGestureRecognizer:swipeUpDown];

13
UISwipeGestureRecognizer *recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(didSwipe:)];
[recognizer setDirection:(UISwipeGestureRecognizerDirectionRight)];
[self.view addGestureRecognizer:recognizer];
[recognizer release];

recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(didSwipe:)];
[recognizer setDirection:(UISwipeGestureRecognizerDirectionLeft)];
[self.view addGestureRecognizer:recognizer];
[recognizer release];

이제 이것은 didSwipe 함수입니다

- (void) didSwipe:(UISwipeGestureRecognizer *)recognizer{
      if([recognizer direction] == UISwipeGestureRecognizerDirectionLeft){
          //Swipe from right to left
          //Do your functions here
      }else{
          //Swipe from left to right
          //Do your functions here
      }
 }

5

Xcode 4.2를 사용하는 경우 스토리 보드 @ 제스처 인식기를 추가 한 다음 GUI 제스처 인식기를 IBActions에 연결할 수 있습니다.

유틸리티 창의 개체 라이브러리 (오른쪽 창 아래쪽)에서 제스처 인식기를 찾을 수 있습니다.

그런 다음 적절한 조치를 취하기 만하면됩니다.


5

네 방향을 모두 감지하려면 해결 방법 에서처럼 네 개의 인스턴스를 만들어야합니다.

이유는 다음과 같습니다 . 작성하는 UISwipeGestureRecognizer 인스턴스와 동일한 인스턴스가 발신자로 선택기에 전달되는 인스턴스입니다. 따라서 네 방향을 모두 인식하도록 설정하면 sgr.direction == xxxxxx가 네 방향 중 하나 인 경우 true를 반환합니다 .

코드를 적게 사용 하는 대체 해결 방법은 다음과 같습니다 (ARC 사용을 가정).

for(int d = UISwipeGestureRecognizerDirectionRight; d <= UISwipeGestureRecognizerDirectionDown; d = d*2) {
    UISwipeGestureRecognizer *sgr = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeFrom:)];
    sgr.direction = d;
    [self.view addGestureRecognizer:sgr];
}

2

다음은 UISwipeGestureRecognizer 사용법에 대한 코드 샘플입니다. 주석을 참고하십시오.

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    //add gesture recognizer. The 'direction' property of UISwipeGestureRecognizer only sets the allowable directions. It does not return to the user the direction that was actaully swiped. Must set up separate gesture recognizers to handle the specific directions for which I want an outcome.
    UISwipeGestureRecognizer *gestureRight;
    UISwipeGestureRecognizer *gestureLeft;
    gestureRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeRight:)];//direction is set by default.
    gestureLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeLeft:)];//need to set direction.
    [gestureLeft setDirection:(UISwipeGestureRecognizerDirectionLeft)];
    //[gesture setNumberOfTouchesRequired:1];//default is 1
    [[self view] addGestureRecognizer:gestureRight];//this gets things rolling.
    [[self view] addGestureRecognizer:gestureLeft];//this gets things rolling.
}

swipeRight 및 swipeLeft는 왼쪽 또는 오른쪽 스 와이프를 기반으로 특정 활동을 수행하는 데 사용하는 방법입니다. 예를 들면 다음과 같습니다.

- (void)swipeRight:(UISwipeGestureRecognizer *)gesture
{
    NSLog(@"Right Swipe received.");//Lets you know this method was called by gesture recognizer.
    NSLog(@"Direction is: %i", gesture.direction);//Lets you know the numeric value of the gesture direction for confirmation (1=right).
    //only interested in gesture if gesture state == changed or ended (From Paul Hegarty @ standford U
    if ((gesture.state == UIGestureRecognizerStateChanged) ||
    (gesture.state == UIGestureRecognizerStateEnded)) {

    //do something for a right swipe gesture.
    }
}

2
UISwipeGestureRecognizer *Updown=[[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(handleGestureNext:)];
            Updown.delegate=self;
            [Updown setDirection:UISwipeGestureRecognizerDirectionDown | UISwipeGestureRecognizerDirectionUp];
            [overLayView addGestureRecognizer:Updown];

            UISwipeGestureRecognizer *LeftRight=[[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(handleGestureNext:)];
            LeftRight.delegate=self;
            [LeftRight setDirection:UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionRight];
            [overLayView addGestureRecognizer:LeftRight];
            overLayView.userInteractionEnabled=NO;


    -(void)handleGestureNext:(UISwipeGestureRecognizer *)recognizer
    {
        NSLog(@"Swipe Recevied");
        //Left
        //Right
        //Top
        //Bottom
    }

2

스위프트 2.1

나는 다음을 사용해야했다

    for var x in [
        UISwipeGestureRecognizerDirection.Left,
        UISwipeGestureRecognizerDirection.Right,
        UISwipeGestureRecognizerDirection.Up,
        UISwipeGestureRecognizerDirection.Down
    ] {
        let r = UISwipeGestureRecognizer(target: self, action: "swipe:")
        r.direction = x
        self.view.addGestureRecognizer(r)
    }

1

흠, 이상해, 그것은 나에게 완벽하게 작동 해, 난 똑같은 일을 해

한번 봐 봐야 할 것 같아

UIGestureRecognizerDelegate 메서드

- (BOOL)gestureRecognizerShouldBegin:(UISwipeGestureRecognizer *)gestureRecognizer {
   // also try to look what's wrong with gesture
   NSLog(@"should began gesture %@", gestureRecognizer);
   return YES;
}

로그에는 다음과 같은 내용이 표시되어야합니다.

제스처를 시작해야한다; target = <(action = actionForUpDownSwipeGestureRecognizer :, target =)>; 방향 = 위, 아래, 왼쪽, 오른쪽>


작동하지 않는 것은 무엇입니까? gestureRecognizerShouldBegin : 제대로 작동합니다.
Danyal Aytekin

1

이것을 사용하면 비트 연산이어야합니다.

   gesture.direction & UISwipeGestureRecognizerDirectionUp || 
   gesture.direction & UISwipeGestureRecognizerDirectionDown

0

이것은 나를 미치게했다. 마지막으로 여러 개의 swipeGestureRecognizer를 사용할 수있는 안정적인 방법을 찾았습니다.

"액션"선택기의 이름이 여러 swipeGestureRecognizer에서 동일한 경우 iOS에 버그가있는 것 같습니다. handleLeftSwipeFrom 및 handleRightSwipeFrom과 같이 이름을 다르게 지정하면 모든 것이 작동합니다.

UISwipeGestureRecognizer *recognizer;

recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleLeftSwipeFrom:)];
[recognizer setDirection:(UISwipeGestureRecognizerDirectionLeft)];
[[self view] addGestureRecognizer:recognizer];
[recognizer release];

recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleRightSwipeFrom:)];
[recognizer setDirection:(UISwipeGestureRecognizerDirectionRight)];
[[self view] addGestureRecognizer:recognizer];
[recognizer release];
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.