If you're using the animateWithDuration:
, I assume you know the final position, right? Then, instead of using SKAction +moveByY:duration:
use SKAction +moveToY:duration:
.
And the "speeding" you want, is a simple timing function, which in the case of an SKAction, can be changed on the instance object SKAction -setTimingMode:
So essentially:
SKAction *action = [SKAction moveToY:someYValue duration:0.15];
action.timingMode = SKActionTimingEaseInEaseOut;
Edit
It's hard for me to assess the issue, there's a lot of things involved, and my knowledge of SpriteKit is not that big, but I know about Core Animation.
My biggest worry is that you're taking values from SpriteKit which may have not been fully committed to the model layer. Notice this term, there are two forms of a layer, the model layer and the presentation layer, the model layer retains the actual properties of a layer, and the presentation layer is a intermediary layer that has the current animated properties. You can actually access all this properties via the view.layer.presentationLayer
.
A general rule of thumb to deal with animations, is to do everything via relative values. So rows that need to move up should do it based on a fixed amount (the sprite's height), so the moveByY:
isn´t as bad as it first seemed, but make sure that everything is relative.
Another alternative, is that you use SKPhysics, where the last row keeps pushing things up, and all the other pieces fall with gravity/bounciness.