Как распознать салфетки во всех четырех направлениях?
Мне нужно распознать звуковые дорожки во всех направлениях (Вверх/Вниз/Влево/Вправо). Не одновременно, но мне нужно их распознать.
Я пробовал:
UISwipeGestureRecognizer *Swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(SwipeRecognizer:)];
Swipe.direction = (UISwipeGestureRecognizerDirectionLeft |
UISwipeGestureRecognizerDirectionRight |
UISwipeGestureRecognizerDirectionDown |
UISwipeGestureRecognizerDirectionUp);
[self.view addGestureRecognizer:Swipe];
[Swipe release];
но ничего не появилось на SwipeRecognizer
Здесь код для SwipeRecognizer:
- (void) SwipeRecognizer:(UISwipeGestureRecognizer *)sender {
if ( sender.direction == UISwipeGestureRecognizerDirectionLeft )
NSLog(@" *** SWIPE LEFT ***");
if ( sender.direction == UISwipeGestureRecognizerDirectionRight )
NSLog(@" *** SWIPE RIGHT ***");
if ( sender.direction == UISwipeGestureRecognizerDirectionDown )
NSLog(@" *** SWIPE DOWN ***");
if ( sender.direction == UISwipeGestureRecognizerDirectionUp )
NSLog(@" *** SWIPE UP ***");
}
Как я могу это сделать? Как назначить моему объекту Swipe все разные направления?
Ответы
Ответ 1
Вы задаете направление, подобное этому
UISwipeGestureRecognizer *Swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(SwipeRecognizer:)];
Swipe.direction = (UISwipeGestureRecognizerDirectionLeft |
UISwipeGestureRecognizerDirectionRight |
UISwipeGestureRecognizerDirectionDown |
UISwipeGestureRecognizerDirectionUp);
То, что будет направлено, когда вы получите обратный вызов, так что это нормально, что все ваши тесты терпят неудачу. Если у вас
- (void) SwipeRecognizer:(UISwipeGestureRecognizer *)sender {
if ( sender.direction | UISwipeGestureRecognizerDirectionLeft )
NSLog(@" *** SWIPE LEFT ***");
if ( sender.direction | UISwipeGestureRecognizerDirectionRight )
NSLog(@" *** SWIPE RIGHT ***");
if ( sender.direction | UISwipeGestureRecognizerDirectionDown )
NSLog(@" *** SWIPE DOWN ***");
if ( sender.direction | UISwipeGestureRecognizerDirectionUp )
NSLog(@" *** SWIPE UP ***");
}
Тесты будут успешными (но все они будут успешными, поэтому вы не получите никакой информации из них). Если вы хотите различать звуковые дорожки в разных направлениях, вам понадобятся отдельные распознаватели жестов.
ИЗМЕНИТЬ
Как указано в комментариях, см. этот ответ. По-видимому, даже это не работает. Вы должны создать салфетки только с одним направлением, чтобы облегчить вашу жизнь.
Ответ 2
К сожалению, вы не можете использовать свойство direction
для прослушивания распознавателя; он только дает вам обнаруженные указания распознающим устройством. Для этой цели я использовал два разных UISwipeGestureRecognizer
, см. Мой ответ здесь: fooobar.com/questions/45938/...
Ответ 3
Я на самом деле столкнулся с этой проблемой. То, что я закончил, это создание подкласса UIView, переопределение touchesMoved:
и выполнение некоторой математики для вычисления направления.
Здесь общая идея:
#import "OmnidirectionalControl.h"
typedef NS_ENUM(NSInteger, direction) {
Down = 0, DownRight = 1,
Right = 2, UpRight = 3,
Up = 4, UpLeft = 5,
Left = 6, DownLeft = 7
};
@interface OmnidirectionalControl ()
@property (nonatomic) CGPoint startTouch;
@property (nonatomic) CGPoint endTouch;
@end
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
self.startTouch = [[touches allObjects][0] locationInView:self];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
self.lastTouch = [[[touches allObjects] lastObject] locationInView:self];
NSLog(@"Direction: %d", [self calculateDirectionFromTouches]);
}
-(direction)calculateDirectionFromTouches {
NSInteger xDisplacement = self.lastTouch.x-self.startTouch.x;
NSInteger yDisplacement = self.lastTouch.y-self.startTouch.y;
float angle = atan2(xDisplacement, yDisplacement);
int octant = (int)(round(8 * angle / (2 * M_PI) + 8)) % 8;
return (direction) octant;
}
Для простоты в touchesMoved:
, я регистрирую только направление, но вы можете делать то, что хотите, с этой информацией (например, передать ее делегату, отправить уведомление с ним и т.д.). В touchesMoved
вам также понадобится какой-то метод, чтобы узнать, закончилась ли салфетка или нет, но это не совсем относится к вопросу, поэтому я оставлю это вам. Математика в calculateDirectionFromTouches
объясняется здесь.
Ответ 4
Наконец-то я нашел самый простой ответ, пожалуйста, отметьте это как ответ, если вы согласитесь.
Если у вас есть только одно направление салфетки + панорама, вы просто говорите: [myPanRecogznier requireGestureRecognizerToFail: mySwipeRecognizer];
Но если у вас есть два или более swipes, вы не можете передать массив в этот метод. Для этого существует UIGestureRecognizerDelegate, который вам нужно реализовать.
Например, если вы хотите распознать 2 щелчка (влево и вправо), и вы также хотите разрешить пользователю панорамировать, вы определяете распознаватели жестов как свойства или переменные экземпляра, а затем вы устанавливаете свой VC в качестве делегата на распознающем жесте:
_swipeLeft = [[UISwipeGestureRecognizer alloc] ...]; // use proper init here
_swipeRight = [[UISwipeGestureRecognizer alloc] ...]; // user proper init here
_swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
_swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
_pan = [[UIPanGestureRecognizer alloc] ...]; // use proper init here
_pan.delegate = self;
// then add recognizers to your view
Затем вы реализуете - (BOOL) gestureRecognizer: (UIGestureRecognizer *) gestureRecognizer shouldRequireFailureOfGestureRecognizer: (UIGestureRecognizer *) otherGestureRecognizer делегировать метод, например:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
if (gestureRecognizer == _pan && (otherGestureRecognizer == _swipeLeft || otherGestureRecognizer == _swipeRight)) {
return YES;
}
return NO;
}
Это говорит распознавателю жесты панорамы работать только в том случае, если оба левого и правого пальцев не распознаются - отлично!
Надеюсь, в будущем Apple просто передаст массив методу requireGestureRecognizerToFail:
Ответ 5
Вы можете добавить только одну диагональ SwipeGesture, затем...
UISwipeGestureRecognizer *swipeV = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(action)];
UISwipeGestureRecognizer *swipeH = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(action)];
swipeH.direction = ( UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionRight );
swipeV.direction = ( UISwipeGestureRecognizerDirectionUp | UISwipeGestureRecognizerDirectionDown );
[self addGestureRecognizer:swipeH];
[self addGestureRecognizer:swipeV];
self.userInteractionEnabled = YES;
Ответ 6
Используйте UIPanGestureRecogizer и определите направления движения, которые вам интересны. дополнительную информацию см. в документации UIPanGestureRecognizer. -rrh
// add pan recognizer to the view when initialized
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panRecognized:)];
[panRecognizer setDelegate:self];
[self addGestureRecognizer:panRecognizer]; // add to the view you want to detect swipe on
-(void)panRecognized:(UIPanGestureRecognizer *)sender
{
if (sender.state == UIGestureRecognizerStateBegan) {
// you might want to do something at the start of the pan
}
CGPoint distance = [sender translationInView:self]; // get distance of pan/swipe in the view in which the gesture recognizer was added
CGPoint velocity = [sender velocityInView:self]; // get velocity of pan/swipe in the view in which the gesture recognizer was added
float usersSwipeSpeed = abs(velocity.x); // use this if you need to move an object at a speed that matches the users swipe speed
NSLog(@"swipe speed:%f", usersSwipeSpeed);
if (sender.state == UIGestureRecognizerStateEnded) {
[sender cancelsTouchesInView]; // you may or may not need this - check documentation if unsure
if (distance.x > 0) { // right
NSLog(@"user swiped right");
} else if (distance.x < 0) { //left
NSLog(@"user swiped left");
}
if (distance.y > 0) { // down
NSLog(@"user swiped down");
} else if (distance.y < 0) { //up
NSLog(@"user swiped up");
}
// Note: if you don't want both axis directions to be triggered (i.e. up and right) you can add a tolerence instead of checking the distance against 0 you could check for greater and less than 50 or 100, etc.
}
}
CHANHE IN STATEEND CODE ЭТОТ
//если ВЫ ХОТИТЕ ТОЛЬКО ОДИНОЧНЫЙ ПЕРЕХОД ИЗ ВВЕРХ, ВНИЗ, ЛЕВЫЙ И ПРАВО
if (sender.state == UIGestureRecognizerStateEnded) {
[sender cancelsTouchesInView]; // you may or may not need this - check documentation if unsure
if (distance.x > 0 && abs(distance.x)>abs(distance.y)) { // right
NSLog(@"user swiped right");
} else if (distance.x < 0 && abs(distance.x)>abs(distance.y)) { //left
NSLog(@"user swiped left");
}
if (distance.y > 0 && abs(distance.y)>abs(distance.x)) { // down
NSLog(@"user swiped down");
} else if (distance.y < 0 && abs(distance.y)>abs(distance.x)) { //up
NSLog(@"user swiped up");
}
}
Ответ 7
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");
}
Ответ 8
Это может быть не лучшее решение, но вы всегда можете указать различный UISwipeGestureRecognizer для каждого направления движения, которое вы хотите обнаружить.
В методе viewDidLoad просто определите требуемый UISwipeGestureRecognizer:
- (void)viewDidLoad{
UISwipeGestureRecognizer *recognizerUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeUp:)];
recognizerUp.direction = UISwipeGestureRecognizerDirectionUp;
[[self view] addGestureRecognizer:recognizerUp];
UISwipeGestureRecognizer *recognizerDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeDown:)];
recognizerDown.direction = UISwipeGestureRecognizerDirectionDown;
[[self view] addGestureRecognizer:recognizerDown];
}
Затем просто примените соответствующие методы для обработки swipes:
- (void)handleSwipeUp:(UISwipeGestureRecognizer *)sender{
if (sender.state == UIGestureRecognizerStateEnded){
NSLog(@"SWIPE UP");
}
}
- (void)handleSwipeDown:(UISwipeGestureRecognizer *)sender{
if (sender.state == UIGestureRecognizerStateEnded){
NSLog(@"SWIPE DOWN");
}
}