UISwipeGestureRecognizer için yön ayarlama


132

Görünüm tabanlı iPhone projeme basit kaydırma hareketi tanıma eklemek istiyorum. Her yöndeki hareketler (sağ, aşağı, sol, yukarı) tanınmalıdır.

UISwipeGestureRecognizer için belgelerde belirtilmiştir:

Bitsel OR işlenenlerini kullanarak birden çok UISwipeGestureRecognizerDirection sabitini belirterek birden çok yön belirtebilirsiniz. Varsayılan yön, UISwipeGestureRecognizerDirectionRight şeklindedir.

Ancak benim için işe yaramıyor. Dört yönün tamamı OR'lendiğinde, yalnızca sola ve sağa kaydırmalar tanınır.

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

Bunu görünüme dört tanıyıcı ekleyerek düzelttim ancak neden belgelerde anlatıldığı gibi çalışmadığını merak ediyorum.

- (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
tamamen ilgisizdir, ancak [super viewDidLoad]; - (void) görünümünde ilk ifade olmalıdırDidLoad
Mihir Mehta

Yanıtlar:


115

Bir böcek var gibi görünüyor. Yaptığınız gibi izin verilen yön (ler) i belirtebilirsiniz. Ancak işlem seçici yönteminde kaydırmayı tetikleyen gerçek yöne erişmeye çalıştığınızda, yine de başlangıçta ayarladığınız bit maskesini alırsınız (izin verilen yönler için).

Bu, 1'den fazla yöne izin verildiğinde gerçek yön kontrollerinin her zaman başarısız olacağı anlamına gelir. Seçici yöntemde (yani -(void)scrollViewSwiped:(UISwipeGestureRecognizer *)recognizer) 'yön' değerini çıktıladığınızda bunu kendiniz için oldukça kolay görebilirsiniz .

Apple'a bir hata raporu (# 8276386) dosyaladı.

[Güncelleme] Apple'dan davranışın amaçlandığı gibi çalıştığını söyleyen bir yanıt aldım.

Örneğin, bir tablo görünümünde bir tablo görünümü hücresinde sola veya sağa kaydırarak 'sil'i tetikleyebilirsiniz (bu, kaydırma hareketinin yönleri sola ve sağa ayarlanmış olur)

Bu, orijinal çözümün kullanılması gereken yol olduğu anlamına gelir. Direction özelliği yalnızca hareketlerin doğru bir şekilde tanınmasını sağlamak için kullanılabilir, ancak tanımayı tetikleyen gerçek yönü karşılaştırmak için başarılı bir tanıma üzerinde gerçekleştirilen yöntemde kullanılamaz.


35
Kaydırma hareketi tanıyıcıyı ilk kullanan hemen hemen herkesin, yön özelliğinin nasıl çalışması gerektiği konusunda aynı yanlış varsayımı yaptığına bahse girerim.
memmons

Yukarı, aşağı, sola ve sağa kaydırmaları izlemek için 4 farklı tanıyıcı oluşturmak zorunda olmak aptalca, ama işte buradasınız.
memmons

vay bu çok berbat, büyük bir anlaşma değil ama
ekleyebilecekleri bir

2
Başlık dosyasında şunlar yazıyor: @property (nonatomic) UISwipeGestureRecognizerDirection direction; // varsayılan, UISwipeGestureRecognizerDirectionRight şeklindedir. kaydırmanın istenen yönü. birden çok yön belirtilebilir
nicktmro

1
Bunun Apple açısından garip bir uygulama gibi göründüğünü kabul etti. Birden çok yön belirtebilmeli ve ardından bu yönlerden birini test edebilmelisiniz.
ChrisP

25

Sol / sağ ve yukarı / aşağı hareketlerin çiftler halinde birlikte çalıştığını fark ettim, bu yüzden sadece iki hareket tanıyıcı belirtmeniz gerekiyor. Ve doktorlar yanlış görünüyor.


Doğru çözüm budur. 2 GR, biri yukarı ve aşağı / biri sol ve sağ için. Bingo!
logancautrell

22

Bu berbat, Lars'ın bahsettiği gibi 2 hareket ekleyerek sorunu çözdüm ve mükemmel çalıştı ...

1) Sol / Sağ 2) Yukarı / Aşağı

  

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

Şimdi bu didSwipe işlevi

- (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 kullanıyorsanız, film şeridinde Hareket Tanıyıcıları ekleyebilir ve ardından GUI Hareket Tanıyıcılarını IBActions'a bağlayabilirsiniz.

Hareket Tanıyıcıları, Yardımcı Program Bölmesinin Nesne Kitaplığında (Sağ bölmenin alt kısmında) bulabilirsiniz.

O zaman bu sadece uygun eyleme Kontrol-sürükleme meselesidir.


5

Dört yönü de algılamasını istiyorsanız, çalışma ortamınızda yaptığınız gibi dört örnek oluşturmanız gerekir.

İşte Nedeni : Oluşturduğunuz aynı UISwipeGestureRecognizer örneği, gönderici olarak seçiciye iletilen örnektir. Dolayısıyla, onu dört yönü de tanıyacak şekilde ayarlarsanız, sgr.direction == xxxxxx dört yönden herhangi biri olduğu için true dönecektir .

Daha az kod içeren alternatif bir çözüm aşağıda verilmiştir (ARC kullanımı varsayılır):

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

İşte UISwipeGestureRecognizer kullanımı için bir kod örneği. Yorumları not edin.

- (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 ve swipeLeft, sola veya sağa kaydırmaya dayalı belirli etkinlikleri gerçekleştirmek için kullandığınız yöntemlerdir. Örneğin:

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

Swift 2.1

Aşağıdakileri kullanmak zorunda kaldım

    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

hmm, garip, benim için mükemmel çalışıyor, tamamen aynı şeyi yapıyorum

bakmayı denemelisin

UIGestureRecognizerDelegate yöntemi

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

günlüklerde aşağıdaki gibi bir şey görmelisiniz:

jest başlamalı; target = <(action = actionForUpDownSwipeGestureRecognizer :, target =)>; yön = yukarı, aşağı, sol, sağ>


Ne çalışmıyor? hareketRecognizerShouldBegin: iyi çalışıyor.
Danyal Aytekin

1

bunu kullan, bit işlemi olmalı

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

0

Bu beni deli ediyordu. Sonunda birden fazla kaydırmalı Hareket Tanıyıcıya sahip olmanın güvenilir bir yolunu buldum.

"İşlem" seçicinizin adının birden çok swipeGestureRecognizer'da aynıysa, iOS'ta bir hata var gibi görünüyor. Bunları farklı bir şekilde adlandırırsanız, örneğin handleLeftSwipeFrom ve handleRightSwipeFrom, her şey çalışır.

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];
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.