Programing

UISwipeGestureRecognizer의 방향 설정

lottogame 2020. 6. 30. 08:22
반응형

UISwipeGestureRecognizer의 방향 설정


뷰 기반 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.");
}

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

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

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

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

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

This means that the original workaround is the way it's supposed to be used. The direction property can only be used to get the gestures recognized correctly, but not in the method performed on a successful recognition to compare for the actual direction that triggered the recognition.


I noticed that left/right and up/down gestures work together in pairs, so you only need to specify two gesture recognizers. And the docs do seem to be wrong.


Well that sucks, I solved the problem by adding 2 gestures like Lars mentioned and that worked perfectly...

1) Left/Right 2) Up/Down

  

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];

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];

Now this is the didSwipe function

- (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
      }
 }

If your using Xcode 4.2 you can add Gesture Recognizers @ the storyboard and then link the GUI Gesture Recognizers to IBActions.

You can find the Gesture Recognizers in the Object Library of the Utility Pane (The bottom of the Right pane).

Then its just a matter of Control-dragging to the appropriate action.


If you want it to detect all four directions, you'll need to create four instances, as you did in your work-around.

Here's Why: The same instance of UISwipeGestureRecognizer that you create is the instance that gets passed to the selector as sender. So if you set it to recognize all four directions, it will return true for sgr.direction == xxx where xxx is any one of the four directions.

Here's an alternative work-around that involves less code (assumes ARC use):

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];
}

Here is a code sample for UISwipeGestureRecognizer usage. Note comments.

- (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 and swipeLeft are methods that you use to perform specific activities based on left or right swiping. For example:

- (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.
    }
}

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
    }

Swift 2.1

I had to use the following

    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)
    }

hmm, strange, it works perfect for me, I do exactly same thing

think you should try look at

UIGestureRecognizerDelegate method

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

in logs you must see something like:

should began gesture ; target= <(action=actionForUpDownSwipeGestureRecognizer:, target=)>; direction = up,down,left,right>


use this, it should be the bit operation

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

This was driving me crazy. I finally figured out a reliable way to have multiple swipeGestureRecognizers.

It appears there is a bug in iOS if the name of your "action" selector is the same across multiple swipeGestureRecognizers. If you just name them differently, e.g. handleLeftSwipeFrom and handleRightSwipeFrom, everything works.

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];

참고URL : https://stackoverflow.com/questions/3319209/setting-direction-for-uiswipegesturerecognizer

반응형