2009-06-19 149 views
4

我正在使用加速度计在UIScrollVIew中滚动多个子视图。当用户向右滑动iPhone时,我想让视图(纵向)滚动到右侧,并在设备向左轻弹时滚动到左侧。如何确定iPhone手摇的方向

我想我可以通过记录正负x加速度值来做到这一点,但我看到这些值通常是正值和负值的混合。我已经设置了1.5g的地板来消除不晃动的运动,并且在0.5秒的时间内观察x值。

我确定有一个三角函数方法来确定轻弹的整体方向,并且您必须在轻弹运动的持续时间内测量值。我也确定有人已经明白了这一点。

有什么想法吗?

谢谢

+2

有比滚动整个iphone更好的滚动手势。 – Brian 2009-06-19 16:10:49

+1

视图已通过手指滑动和触摸UIPageControl进行滚动。这更多的是练习使用加速度计获得一些经验。但它似乎是一个简单的方法在这些子视图之间滚动,这些子视图是流程中编号的步骤。我已经有了滚动功能,但是直到我可以确定方向为止,我只能向一个方向滚动。 – Alpinista 2009-06-19 16:15:54

回答

5

好的,算出了一个解决方案。当我检测到摇晃动作(x轴上的加速度大于1.5)时,我启动计时器并将BOOL设置为true。虽然BOOL是真的,我加入加速度值。当计时器到期时,我停止添加加速度值,并根据总加速度的符号确定摇动的方向。


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

注:我不能让<和>符号正确的代码块上面的格式,所以我取代isLessThan和isGreaterThan的符号。

6

我开发了一个解决方案,它给了我比建议的解决方案更好的反馈(仅适用于左右摇动)。 我没有在这里的方式是相当敏感(识别小震动),但灵敏度可以通过改变tresholdFirstMove和tresholdBackMove(增幅为低灵敏度)

在斯威夫特进行调整: (在你的viewController并添加“导入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/") 
      } 
     } 
    } 

}