Mengatur arah untuk UISwipeGestureRecognizer

132

Saya ingin menambahkan pengenalan gerakan gesek sederhana ke proyek iPhone berbasis tampilan saya. Gerakan di semua arah (kanan, bawah, kiri, atas) harus dikenali.

Itu dinyatakan dalam dokumen untuk UISwipeGestureRecognizer:

Anda dapat menentukan beberapa arah dengan menetapkan beberapa konstanta UISwipeGestureRecognizerDirection menggunakan bitwise-OR operan. Arah default adalah UISwipeGestureRecognizerDirectionRight.

Namun bagi saya itu tidak berhasil. Ketika keempat arah di OR'ed hanya geseran ke kiri dan kanan yang dikenali.

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

Saya memperbaikinya dengan menambahkan empat pengenal pada tampilan, tetapi saya ingin tahu mengapa tidak berfungsi seperti yang diiklankan dalam dokumen?

- (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
sumber
3
sepenuhnya tidak terkait, tetapi [super viewDidLoad]; seharusnya menjadi pernyataan pertama di - (void) viewDidLoad
Mihir Mehta

Jawaban:

115

Sepertinya ada bug. Anda dapat menentukan arah yang diizinkan seperti yang Anda lakukan. Tetapi ketika Anda mencoba mengakses arah aktual yang memicu gesekan dalam metode pemilih tindakan Anda masih mendapatkan topeng bit yang Anda atur awalnya (untuk arah yang diizinkan).

Ini berarti bahwa pemeriksaan untuk arah aktual akan selalu gagal ketika lebih dari 1 arah diizinkan. Anda dapat melihatnya sendiri dengan mudah ketika Anda menampilkan nilai 'arah' dalam metode pemilih (yaitu -(void)scrollViewSwiped:(UISwipeGestureRecognizer *)recognizer).

Mengajukan laporan bug (# 8276386) ke Apple.

[Pembaruan] Saya mendapat jawaban dari Apple yang mengatakan bahwa perilakunya berfungsi sebagaimana mestinya.

Jadi misalnya dalam tampilan tabel Anda dapat menggesek ke kiri atau ke kanan dalam sel tampilan tabel untuk memicu 'hapus' (ini akan memiliki arah gerakan swipe diatur ke kiri dan kanan)

Ini berarti bahwa solusi asli adalah cara yang seharusnya digunakan. Properti arah hanya dapat digunakan untuk membuat gerakan dikenali dengan benar, tetapi tidak dalam metode yang dilakukan pada pengakuan yang berhasil untuk membandingkan untuk arah aktual yang memicu pengakuan.

RupertP
sumber
35
Saya berani bertaruh bahwa hampir semua orang yang pertama kali menggunakan penggeser isyarat menggesek membuat asumsi salah yang sama persis tentang bagaimana properti arah harus bekerja.
memmons
Sungguh konyol harus membuat 4 pengenal berbeda untuk melacak gesekan ke atas, ke bawah, ke kiri dan ke kanan, tetapi di sanalah Anda.
memmons
wow itu agak menyebalkan, bukan masalah besar tapi sepertinya sesuatu yang bisa mereka tambahkan
marchinram
2
File header mereka mengatakan: @property (nonatomic) UISwipeGestureRecognizerDirection arah; // defaultnya adalah UISwipeGestureRecognizerDirectionRight. arah gesek yang diinginkan. beberapa arah dapat ditentukan
nicktmro
1
Setuju bahwa ini sepertinya implementasi aneh di pihak Apple. Anda harus dapat menentukan beberapa arah dan kemudian menguji salah satu dari arah itu.
ChrisP
25

Saya perhatikan bahwa gerakan kiri / kanan dan atas / bawah bekerja bersama secara berpasangan, jadi Anda hanya perlu menentukan dua pengenal isyarat. Dan dokumen itu tampaknya salah.

Lars
sumber
Ini solusi yang tepat. 2 GR, satu untuk atas dan ke bawah / satu untuk kiri dan kanan. Bingo!
logancautrell
22

Nah itu menyebalkan, saya memecahkan masalah dengan menambahkan 2 gerakan seperti yang disebutkan Lars dan itu bekerja dengan sempurna ...

1) Kiri / Kanan 2) Atas / Bawah

  

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

Sekarang ini adalah fungsi 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
      }
 }
KarenAnne
sumber
5

Jika Anda menggunakan Xcode 4.2, Anda dapat menambahkan Gesture Recognizers @ storyboard dan kemudian menautkan GUI Gesture Recognizers ke IBActions.

Anda dapat menemukan Pengenal Gerakan di Perpustakaan Objek pada Panel Utilitas (Bagian bawah panel Kanan).

Maka itu hanya masalah Kontrol-menyeret ke tindakan yang sesuai.

Grymm
sumber
5

Jika Anda ingin mendeteksi keempat arah, Anda harus membuat empat instance, seperti yang Anda lakukan di sekitar.

Inilah Alasannya : Contoh yang sama dari UISwipeGestureRecognizer yang Anda buat adalah contoh yang akan diteruskan ke pemilih sebagai pengirim. Jadi jika Anda mengaturnya untuk mengenali keempat arah, itu akan mengembalikan true untuk di sgr.direction == xxxmana xxx adalah salah satu dari empat arah.

Berikut ini penyelesaian alternatif yang melibatkan lebih sedikit kode (mengasumsikan penggunaan 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];
}
tybro0103
sumber
2

Berikut adalah contoh kode untuk penggunaan UISwipeGestureRecognizer. Catat komentar.

- (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 dan swipeLeft adalah metode yang Anda gunakan untuk melakukan aktivitas tertentu berdasarkan swiping kiri atau kanan. Sebagai contoh:

- (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
sumber
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
sumber
2

Cepat 2.1

Saya harus menggunakan yang berikut ini

    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
sumber
1

hmm, aneh, itu berfungsi sempurna untuk saya, saya melakukan hal yang persis sama

pikir kamu harus coba lihat

Metode UIGestureRecognizerDelegate

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

dalam log Anda harus melihat sesuatu seperti:

harus mulai gerakan; target = <(action = actionForUpDownSwipeGestureRecognizer :, target =)>; arah = atas, bawah, kiri, kanan>

iFreeman
sumber
Apa yang tidak berhasil? gestureRecognizerShouldBegin: berfungsi dengan baik.
Danyal Aytekin
1

gunakan ini, itu harus operasi bit

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

Ini membuatku gila. Saya akhirnya menemukan cara yang dapat diandalkan untuk memiliki beberapa swipeGestureRecognizers.

Tampaknya ada bug di iOS jika nama pemilih "action" Anda sama di beberapa swipeGestureRecognizers. Jika Anda hanya menamainya secara berbeda, mis. HandleLeftSwipeFrom dan handleRightSwipeFrom, semuanya berfungsi.

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
sumber