2009-06-19 11 views
4

J'utilise l'accéléromètre pour faire défiler plusieurs sous-vues dans un UIScrollVIew. Je souhaite que la vue (orientation portrait) défile vers la droite lorsque l'utilisateur bascule l'iPhone vers la droite et défile vers la gauche lorsque l'appareil est déplacé vers la gauche. Je pensais pouvoir le faire simplement en notant des valeurs d'accélération x positives ou négatives, mais je vois que les valeurs sont généralement un mélange de valeurs positives et négatives. J'ai mis le plancher à 1.5g pour éliminer les mouvements sans secousse, et je regarde les valeurs x sur une durée de .5 secondes.Comment déterminer la direction d'un tremblement de l'iPhone

Je suis sûr qu'il existe une méthode trigonométrique pour déterminer la direction générale d'un film, et que vous devez mesurer des valeurs sur la durée du mouvement de film. Je suis également sûr que quelqu'un a déjà compris celui-ci.

Des idées là-bas?

Merci

+2

Il y a de meilleurs gestes pour faire défiler que de feuilleter l'ensemble de l'iPhone. – Brian

+1

La vue défile déjà avec le doigt et en touchant un UIPageControl. C'est plus un exercice pour acquérir de l'expérience en utilisant l'accéléromètre. Mais cela semble être un moyen facile de faire défiler ces sous-vues, qui sont des étapes numérotées dans un processus. J'ai déjà fait défiler le défilement, mais jusqu'à ce que je puisse déterminer la direction, je ne peux que défiler dans une direction. – Alpinista

Répondre

5

OK, a élaboré une solution. Lorsque je détecte un mouvement de secousse (accélération supérieure à 1,5 sur l'axe des x), je lance une minuterie et règle un BOOL sur vrai. Alors que le BOOL est vrai, j'ajoute des valeurs d'accélération. Lorsque le chronomètre expire, j'arrête d'ajouter des valeurs d'accélération et de déterminer la direction du tremblement par le signe de l'accélération totale.


- (void)accelerometer:(UIAccelerometer *)acel didAccelerate:(UIAcceleration *)aceler { 

    if (fabsf(aceler.x) > 1.5) 
    { 
     shake = YES; 
     NSTimeInterval myInterval = .75; 
     [NSTimer scheduledTimerWithTimeInterval:myInterval target:self selector:@selector(endShake) userInfo:nil repeats:NO]; 
     return; 
    } 

    if(shake) 
    { 
     totalG += aceler.x; 
    } 
} 

- (void) endShake { 
    shake = NO; 
    int direction; 
    if (totalG isLessThan 0) direction = 1; 
    if(totalG isGreaterThan 0) direction = -1; 
    [self changePageByShake:direction]; 
    totalG = 0; 
} 

Note: Je ne pouvais pas les < et> symboles pour formater correctement dans le bloc de code ci-dessus, donc je substitué isLessThan et isGreaterThan pour les symboles.

+0

Pouvez-vous s'il vous plaît dire comment pouvons-nous détecter le geste de haut en bas? – Dhara

6

J'ai développé une solution qui me donne un meilleur retour que la solution proposée (seulement pour les secousses gauche et droite). La façon dont je l'ai fait ici est très sensible (reconnaît une petite secousse), mais la sensibilité peut être adaptée en changeant tresholdFirstMove et tresholdBackMove (augmentation de la sensibilité plus faible)

Swift:. (dans votre viewController et ajouter « importation CoreMotion ")

var startedLeftTilt = false 
var startedRightTilt = false 
var dateLastShake = NSDate(timeIntervalSinceNow: -2) 
var dateStartedTilt = NSDate(timeIntervalSinceNow: -2) 
var motionManager = CMMotionManager() 
let tresholdFirstMove = 3.0 
let tresholdBackMove = 0.5 

override func viewDidLoad() { 
    // your code 

    motionManager.gyroUpdateInterval = 0.01 
} 

override func viewDidAppear(animated: Bool) { 
    super.viewDidAppear(animated) 

    motionManager.startGyroUpdatesToQueue(NSOperationQueue.currentQueue(), withHandler: { (gyroData, error) -> Void in 
     self.handleGyroData(gyroData.rotationRate) 
    }) 

} 

private func handleGyroData(rotation: CMRotationRate) { 

    if fabs(rotation.z) > tresholdFirstMove && fabs(dateLastShake.timeIntervalSinceNow) > 0.3 
    { 
     if !startedRightTilt && !startedLeftTilt 
     { 
      dateStartedTilt = NSDate() 
      if (rotation.z > 0) 
      { 
       startedLeftTilt = true 
       startedRightTilt = false 
      } 
      else 
      { 
       startedRightTilt = true 
       startedLeftTilt = false 
      } 
     } 
    } 

    if fabs(dateStartedTilt.timeIntervalSinceNow) >= 0.3 
    { 
     startedRightTilt = false 
     startedLeftTilt = false 
    } 
    else 
    { 
     if (fabs(rotation.z) > tresholdBackMove) 
     { 
      if startedLeftTilt && rotation.z < 0 
      { 
       dateLastShake = NSDate() 
       startedRightTilt = false 
       startedLeftTilt = false 

       println("\\\n Shaked left\n/") 
      } 
      else if startedRightTilt && rotation.z > 0 
      { 
       dateLastShake = NSDate() 
       startedRightTilt = false 
       startedLeftTilt = false 

       println("\\\n Shaked right\n/") 
      } 
     } 
    } 

} 
Questions connexes