2010-08-27 4 views
2

Я знаю, что UIRotateGestureRecognizer уже является частью iOS. Но этот жест требовал двух пальцев. Как я могу реализовать аналогичный распознаватель жестов, требующий только одного пальца? В AppStore - Gyrotate есть игра с довольно хорошей реализацией этого. Любые подсказки приветствуются. Спасибо.Как реализовать распознаватель жестов с одним пальцем?

+0

Только FWIW - лучший подход состоит в том, чтобы понять, что в принципе, если производная касательной гладкая, это, вероятно, хорошая круговая дуга, которую пользователь рисует. Производная касательной очень легко вычислить, концептуально и требует небольшого состояния - вам нужно только проверить последние два кадра! Это «магический» алгоритм распознавания сегментов дуги. – Fattie

ответ

5

Вот код - он работает на моем симуляторе. Марк ответил, что это то, что вы искали.

// On new touch, start a new array of points 
- (void) touchesBegan:(NSSet *) touches withEvent:(UIEvent *) event 
{ 
    self.points = [NSMutableArray array]; 
    CGPoint pt = [[touches anyObject] locationInView:self]; 
    [self.points addObject:[NSValue valueWithCGPoint:pt]]; 
} 

// Add each point to the array 
- (void) touchesMoved:(NSSet *) touches withEvent:(UIEvent *) event 
{ 
    CGPoint pt = [[touches anyObject] locationInView:self]; 
    [self.points addObject:[NSValue valueWithCGPoint:pt]]; 
    [self setNeedsDisplay]; 
} 

// At the end of touches, determine whether a circle was drawn 
- (void) touchesEnded:(NSSet *) touches withEvent:(UIEvent *) event 
{ 
    if (!self.points) return; 
    if (self.points.count < 3) return; 

    // Test 1: The start and end points must be between 60 pixels of each other 
    CGRect tcircle; 
    if (distance(POINT(0), POINT(self.points.count - 1)) < 60.0f) 
     tcircle = [self centeredRectangle]; 

    // Test 2: Count the distance traveled in degrees. Must fall within 45 degrees of 2 PI 
    CGPoint center = CGPointMake(CGRectGetMidX(tcircle), CGRectGetMidY(tcircle)); 
    float distance = ABS(acos(dotproduct(centerPoint(POINT(0), center), centerPoint(POINT(1), center)))); 
    for (int i = 1; i < (self.points.count - 1); i++) 
     distance += ABS(acos(dotproduct(centerPoint(POINT(i), center), centerPoint(POINT(i+1), center)))); 
    if ((ABS(distance - 2 * M_PI) < (M_PI/4.0f))) circle = tcircle; 

    [self setNeedsDisplay]; 
} 
+2

Не то, что решило мою проблему, но вызвало момент ахи, который привел к моему окончательному решению. – user292953

+0

доля прочь тогда – amok

+1

ах отлично это то, что я искал, а также <3 –

2

Попробуйте исследовать UIGestureRecognizer Класс. Вы должны быть в состоянии настроить его, используя UIGestureRecognizerDelegate

6

Кирби Turner имеет полный один палец вращения жест распознаватель here.

+0

Как я могу выполнять как ротацию, так и перевод с помощью этого кода? – user930195

+0

Вы продолжаете спрашивать о выполнении «обоих». если вы хотите обнаружить ДВА ОТДЕЛЬНЫХ жестов, просто используйте два (или более) UIGestureRecogniser. – Fattie

2

Я реализовал IQStickerView с OneFingerRotation, Scale, Resize и Закрыть особенность.

Особенности: -

1) One Finger Rotation Scale.

2) Одно изменение размера пальца.

3) Enable/Desable Rotation, Scale, Resize со свойствами.

4) Автоматическое управление несколькими IQStickerView.

5) Может также работать с UIScrollView.

6) Быстрая оперативность.

GitHub инструмента для репозиции здесь: - https://github.com/hackiftekhar/IQStickerView

1

Реализован с панорамированием жеста распознаванью, это какое-то другой UIView, что этот жест распознавань прикрепляется к, но он должен работать с ней прилагается к виду вы хотите повернуть.

- (void) gestureRotateButtonPan:(UIPanGestureRecognizer*) gestureRecognizer { 

    switch (gestureRecognizer.state) { 
     case UIGestureRecognizerStatePossible: 
      break; 
     case UIGestureRecognizerStateBegan: 
     { 
      CGPoint location = [gestureRecognizer translationInView:[gestureRecognizer view]]; 
      _touchRotateStartPoint = [self convertPoint:location fromView:[gestureRecognizer view]]; 
     } 
      break; 
     case UIGestureRecognizerStateChanged: 
     { 
      CGPoint imageLocation = CGPointMake(self.mainImageView.transform.tx + self.mainImageView.center.x 
               , self.mainImageView.transform.ty + self.mainImageView.center.y); 
      CGPoint buttonLocation = [gestureRecognizer translationInView:self]; 
      buttonLocation.x += _touchRotateStartPoint.x; 
      buttonLocation.y += _touchRotateStartPoint.y; 

      CGFloat currentRotation = atan2(buttonLocation.y - imageLocation.y, buttonLocation.x - imageLocation.x) 
             - atan2(_touchRotateStartPoint.y - imageLocation.y, _touchRotateStartPoint.x - imageLocation.x); 

      CGFloat rotation = -(_lastRotation - currentRotation); 
      CGAffineTransform currentTransform = self.mainImageView.transform; 
      CGAffineTransform rotatedTransform = CGAffineTransformRotate(currentTransform, rotation); 
      self.mainImageView.transform = rotatedTransform; 

      [self setNeedsDisplay]; 
     } 
      break; 
     case UIGestureRecognizerStateCancelled: 
     case UIGestureRecognizerStateEnded: 
      _lastRotation = 0.0; 
      break; 
     case UIGestureRecognizerStateFailed: 
      break; 
     default: 
      break; 
    } 
} 
Смежные вопросы