Festlegen der Richtung für UISwipeGestureRecognizer

132

Ich möchte meinem ansichtsbasierten iPhone-Projekt eine einfache Wischgestenerkennung hinzufügen. Gesten in alle Richtungen (rechts, unten, links, oben) sollten erkannt werden.

In den Dokumenten für UISwipeGestureRecognizer wird Folgendes angegeben:

Sie können mehrere Richtungen angeben, indem Sie mehrere UISwipeGestureRecognizerDirection-Konstanten mit bitweisen ODER-Operanden angeben. Die Standardrichtung ist UISwipeGestureRecognizerDirectionRight.

Bei mir funktioniert es jedoch nicht. Wenn alle vier Richtungen ODER-verknüpft sind, werden nur linke und rechte Wischbewegungen erkannt.

- (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.");
}

Ich habe dies behoben, indem ich der Ansicht vier Erkenner hinzugefügt habe, aber ich bin gespannt, warum es nicht wie in den Dokumenten angegeben funktioniert hat.

- (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.");
}
Sandisn
quelle
3
es ist völlig unabhängig, aber [super viewDidLoad]; sollte erste Aussage in - (void) viewDidLoad
Mihir Mehta

Antworten:

115

Scheint, als gäbe es einen Fehler. Sie können die zulässige (n) Richtung (en) wie angegeben angeben. Wenn Sie jedoch versuchen, auf die tatsächliche Richtung zuzugreifen , die das Wischen in der Aktionsauswahlmethode ausgelöst hat, erhalten Sie immer noch die ursprünglich festgelegte Bitmaske (für die zulässigen Richtungen).

Dies bedeutet, dass die Überprüfung der tatsächlichen Richtung immer fehlschlägt, wenn mehr als eine Richtung zulässig ist. Sie können es ganz leicht selbst sehen, wenn Sie den Wert 'Richtung' in der Auswahlmethode (dh -(void)scrollViewSwiped:(UISwipeGestureRecognizer *)recognizer) ausgeben .

Hat einen Fehlerbericht (# 8276386) an Apple gesendet.

[Update] Ich habe eine Antwort von Apple erhalten, dass das Verhalten wie beabsichtigt funktioniert.

So können Sie beispielsweise in einer Tabellenansicht in einer Tabellenansichtszelle nach links oder rechts wischen, um "Löschen" auszulösen (hier wäre die Richtung der Wischgeste auf links und rechts eingestellt).

Dies bedeutet, dass die ursprüngliche Problemumgehung so ist, wie sie verwendet werden soll. Die Richtungseigenschaft kann nur verwendet werden, um die Gesten korrekt zu erkennen, nicht jedoch bei der Methode, die bei einer erfolgreichen Erkennung ausgeführt wird, um die tatsächliche Richtung zu vergleichen, die die Erkennung ausgelöst hat.

RupertP
quelle
35
Ich bin bereit zu wetten, dass fast jeder, der zuerst die Wischgestenerkennung verwendet, genau die gleiche falsche Annahme darüber macht, wie die Richtungseigenschaft funktionieren soll.
Memmons
Es ist albern, 4 verschiedene Erkenner erstellen zu müssen, um nach oben, unten, links und rechts zu streichen, aber da sind Sie.
Memmons
Wow, das ist ein
bisschen scheiße
2
Die Header-Datei lautet: @property (nichtatomar) UISwipeGestureRecognizerDirection direction; // Standard ist UISwipeGestureRecognizerDirectionRight. die gewünschte Richtung des Wischens. Es können mehrere Richtungen angegeben werden
nicktmro
1
Einverstanden, dass dies eine seltsame Implementierung von Apple zu sein scheint. Sie sollten in der Lage sein, mehrere Richtungen anzugeben und dann auf eine dieser Richtungen zu testen.
ChrisP
25

Mir ist aufgefallen, dass die Gesten links / rechts und oben / unten paarweise zusammenarbeiten, sodass Sie nur zwei Gestenerkenner angeben müssen. Und die Dokumente scheinen falsch zu sein.

Lars
quelle
Dies ist die richtige Lösung. 2 GRs, eine für oben und unten / eine für links und rechts. Bingo!
Logancautrell
22

Nun, das ist scheiße, ich habe das Problem gelöst, indem ich 2 Gesten hinzugefügt habe, wie Lars es erwähnt hat, und das hat perfekt funktioniert ...

1) Links / Rechts 2) Auf / Ab

  

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

Dies ist die didSwipe-Funktion

- (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
      }
 }
KarenAnne
quelle
5

Wenn Sie Xcode 4.2 verwenden, können Sie Gestenerkenner im Storyboard hinzufügen und dann die GUI-Gestenerkenner mit IBActions verknüpfen.

Sie finden die Gestenerkenner in der Objektbibliothek des Utility-Bereichs (unten im rechten Bereich).

Dann ist es nur noch eine Frage des Strichziehens zur entsprechenden Aktion.

Grymm
quelle
5

Wenn Sie möchten, dass alle vier Richtungen erkannt werden, müssen Sie wie bei Ihrer Umgehung vier Instanzen erstellen.

Hier ist der Grund: Dieselbe Instanz von UISwipeGestureRecognizer, die Sie erstellen, ist die Instanz, die als Absender an den Selektor übergeben wird. Wenn Sie also festlegen, dass alle vier Richtungen erkannt werden, wird true für zurückgegebensgr.direction == xxx wenn xxx eine der vier Richtungen ist.

Hier ist eine alternative Problemumgehung , die weniger Code erfordert (setzt die Verwendung von ARC voraus):

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];
}
tybro0103
quelle
2

Hier ist ein Codebeispiel für die Verwendung von UISwipeGestureRecognizer. Kommentare beachten.

- (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 und swipeLeft sind Methoden, mit denen Sie bestimmte Aktivitäten basierend auf dem Wischen nach links oder rechts ausführen. Beispielsweise:

- (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.
    }
}
Greg
quelle
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
    }
Bhavik
quelle
2

Swift 2.1

Ich musste folgendes verwenden

    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)
    }
Andrei
quelle
1

hmm, seltsam, es funktioniert perfekt für mich, ich mache genau das gleiche

denke, du solltest es dir ansehen

UIGestureRecognizerDelegate-Methode

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

In Protokollen müssen Sie Folgendes sehen:

sollte Geste beginnen; target = <(action = actionForUpDownSwipeGestureRecognizer:, target =)>; Richtung = oben, unten, links, rechts>

iFreeman
quelle
Was funktioniert nicht? gestureRecognizerShouldBegin: funktioniert einwandfrei.
Danyal Aytekin
1

Verwenden Sie dies, es sollte die Bit-Operation sein

   gesture.direction & UISwipeGestureRecognizerDirectionUp || 
   gesture.direction & UISwipeGestureRecognizerDirectionDown
William Wu
quelle
0

Das hat mich verrückt gemacht. Ich habe endlich einen zuverlässigen Weg gefunden, um mehrere swipeGestureRecognizer zu haben.

Es scheint, dass es in iOS einen Fehler gibt, wenn der Name Ihres "Aktions" -Selektors für mehrere swipeGestureRecognizer gleich ist. Wenn Sie sie nur anders benennen, z. B. handleLeftSwipeFrom und handleRightSwipeFrom, funktioniert alles.

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