模拟对象的惯性滚动

时间:2013-09-17 10:07:24

标签: iphone ios ipad cocoa-touch

我有一个物体需要拖动和模拟惯性滚动。

到目前为止,这是我工作迟缓的原因。

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint touchLocation = [touch locationInNode:self];

    self.lastTouch = touchLocation;
    self.lastTimestamp = event.timestamp;
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint currentLocation = [touch locationInNode:self];

    // how much it scrolled vertically (it is a table view, no need to scroll horizontally)
    CGFloat deltaY = currentLocation.y - self.lastTouch.y;

    // move the container (that is the object I want to implement the inertial movement)
    // to the correct position
    CGPoint posActual = self.container.position; 
    posActual.y = posActual.y + deltaY;
    [self.container setPosition:posActual];


    // calculate the movement speed
    NSTimeInterval deltaTime = event.timestamp - self.lastTimestamp;
    self.speedY = deltaY / deltaTime;

    self.lastTouch = currentLocation;
    self.lastTimestamp = event.timestamp;

}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    CGFloat tempoDecay = 0.4f;

    CGPoint finalPosition = self.container.position;
    finalPosition.y = finalPosition.y + (self.speedY * tempoDecay);

    // move the object to the final position using easeOut timing...

}

这就是我所看到的:我刷它。当我抬起手指时,它会加速,然后突然停止。我记录了speedY值,值很大,比如720! (每秒720像素?)

我不能使用UIScrollView或Apple提供的其他方法。它是一个必须单独滚动惯性的物体。感谢。

2 个答案:

答案 0 :(得分:5)

我通过在场景的更新方法中添加“惯性制动”来实现这种惯性滚动(一个SKSpriteNode对象垂直填充多个精灵以模拟垂直滚动选择)

// add the variables as member variables to your class , setup with initial values on your init 
  SKSpriteNode *mList // this is the sprite node that will be our scroll object
  mTouching = NO;         // BOOL
  mLastScrollDist = 0.0f; // float
在你的touchesBegan中,将mTouching更改为YES,表示触摸有效..

在你的touchesMoved中,计算mLastScrollDist = previousLocation.y - currentlocation.y,然后将其添加到mList的y位置(mList.y + = mLastScrollDist)

在你的touchesEnded中,将mTouching改为NO

最后在场景的更新方法中,计算制动惯性效应

- (void)update:(NSTimeInterval)currentTime
{
    if (!mTouching)
    {
        float slowDown = 0.98f;

        if (fabsf(mLastScrollDist) < 0.5f)
            slowDown = 0;

        mLastScrollDist *= slowDown;
        mList.y += mLastScrollDist; // mList is the SKSpriteNode list object
    }
}

答案 1 :(得分:1)

在滑动过程中,

touchesMoved会多次调用。并且每个呼叫的两个点之间的距离是15-30个像素。让滑动持续0.5秒,然后调用该方法10次。 speedY = 30 / 0.05 = 600。

也只考虑了最后一次“touchesMoved speed”。也许你需要计算平均速度?