Chcę dodać proste rozpoznawanie gestów przesunięcia do mojego projektu iPhone'a opartego na widoku. Należy rozpoznawać gesty we wszystkich kierunkach (w prawo, w dół, w lewo, w górę).
Jest to określone w dokumentacji dla UISwipeGestureRecognizer:
Możesz określić wiele kierunków, określając wiele stałych UISwipeGestureRecognizerDirection przy użyciu operandów bitowych-OR. Domyślnym kierunkiem jest UISwipeGestureRecognizerDirectionRight.
Jednak dla mnie to nie działa. Gdy wszystkie cztery kierunki zostaną wykonane LUB rozpoznawane są tylko przesunięcia w lewo i w prawo.
- (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.");
}
Naprawiłem to, dodając cztery narzędzia rozpoznające do widoku, ale jestem ciekawy, dlaczego nie działa tak, jak reklamowano w dokumentach?
- (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.");
}
ios
iphone
swipe
uiswipegesturerecognizer
sandisn
źródło
źródło
Odpowiedzi:
Wygląda na to, że jest błąd. Możesz określić dozwolone kierunki, tak jak zrobiłeś. Ale kiedy próbujesz uzyskać dostęp do rzeczywistego kierunku, który wywołał przesunięcie w metodzie selektora akcji, nadal uzyskujesz pierwotnie ustawioną maskę bitową (dla dozwolonych kierunków).
Oznacza to, że sprawdzenie rzeczywistego kierunku zawsze kończy się niepowodzeniem, gdy dozwolony jest więcej niż 1 kierunek. Możesz to zobaczyć na własne oczy, gdy podajesz wartość 'direction' w metodzie selektora (tj
-(void)scrollViewSwiped:(UISwipeGestureRecognizer *)recognizer
.).Zgłosił błąd (nr 8276386) do Apple.
[Aktualizacja] Otrzymałem odpowiedź od Apple, mówiącą, że zachowanie działa zgodnie z zamierzeniami.
Na przykład w widoku tabeli możesz przesunąć palcem w lewo lub w prawo w komórce widoku tabeli, aby wywołać `` usuwanie '' (to miałoby kierunki gestu przesunięcia ustawione na lewo i prawo)
Oznacza to, że pierwotne obejście jest sposobem, w jaki powinno być używane. Właściwość direction może być używana tylko do prawidłowego rozpoznawania gestów, ale nie w metodzie wykonanej po pomyślnym rozpoznaniu, aby porównać rzeczywisty kierunek, który wyzwolił rozpoznanie.
źródło
Zauważyłem, że gesty w lewo / w prawo i w górę / w dół działają razem w parach, więc wystarczy określić dwa urządzenia do rozpoznawania gestów. A doktorzy wydają się być w błędzie.
źródło
Cóż, to jest do bani, rozwiązałem problem, dodając 2 gesty, takie jak wspomniał Lars, i działało idealnie ...
1) Lewo / Prawo 2) Góra / Dół
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];
źródło
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];
To jest funkcja 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 } }
źródło
Jeśli używasz Xcode 4.2, możesz dodać Gesture Recognizers @ the storyboard, a następnie połączyć GUI Gesture Recognizers z IBActions.
Rozpoznawanie gestów można znaleźć w bibliotece obiektów w okienku narzędziowym (na dole prawego panelu).
Wtedy wystarczy przeciągnąć klawisz Control do odpowiedniego działania.
źródło
Jeśli chcesz, aby wykrywał wszystkie cztery kierunki, musisz utworzyć cztery instancje, tak jak w przypadku obejścia.
Oto dlaczego : To samo wystąpienie UISwipeGestureRecognizer, które tworzysz, jest instancją, która jest przekazywana do selektora jako nadawca. Więc jeśli ustawisz rozpoznawanie wszystkich czterech kierunków, zwróci prawdę, gdy
sgr.direction == xxx
xxx jest jednym z czterech kierunków.Oto alternatywne obejście, które obejmuje mniej kodu (zakłada użycie 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]; }
źródło
Swift 2.1
Musiałem użyć następującego
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) }
źródło
Oto przykład kodu do użycia UISwipeGestureRecognizer. Uwaga komentarze.
- (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 i swipeLeft to metody używane do wykonywania określonych czynności na podstawie przesuwania w lewo lub w prawo. Na przykład:
- (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. } }
źródło
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 }
źródło
hmm, dziwne, u mnie działa idealnie, robię dokładnie to samo
myślę, że powinieneś spróbować spojrzeć
UIGestureRecognizerDelegate, metoda
- (BOOL)gestureRecognizerShouldBegin:(UISwipeGestureRecognizer *)gestureRecognizer { // also try to look what's wrong with gesture NSLog(@"should began gesture %@", gestureRecognizer); return YES; }
w logach musisz zobaczyć coś takiego:
powinien zacząć gest; target = <(action = actionForUpDownSwipeGestureRecognizer :, target =)>; kierunek = góra, dół, lewo, prawo>
źródło
użyj tego, powinna to być operacja bitowa
gesture.direction & UISwipeGestureRecognizerDirectionUp || gesture.direction & UISwipeGestureRecognizerDirectionDown
źródło
To doprowadzało mnie do szału. W końcu znalazłem niezawodny sposób na posiadanie wielu swipeGestureRecognizers.
Wygląda na to, że w systemie iOS występuje błąd, jeśli nazwa selektora „akcji” jest taka sama dla wielu urządzeń swipeGestureRecognizers. Jeśli nadasz im inną nazwę, np. HandleLeftSwipeFrom i handleRightSwipeFrom, wszystko działa.
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];
źródło