すべてが落ち着いたら、アニメーターが一時停止する必要があるというあなたの意見は正しいです。
重力の動作に何items
が関連付けられているかを確認し、他のアイテムがまだ落下していないことを確認してください。たとえば、次のバグを誤って作成するのは簡単です。
- 重力と衝突にビューを追加する
- スーパービューと衝突からビューを削除
- 重力からビューを削除できません
このままでは「ゴーストアイテム」が永遠に落ちてしまいます。
もう 1 つの考えられる問題 (あなたの説明を考えると可能性は低いですが) は、あなたのアイテムが、無限ではあるが小さい「バウンス」を引き起こしている他の動作に関連付けられている場合です。アニメーターの動作の完全なリストを確認します (子の動作も確認することを忘れないでください)。UIDynamicItemBehavior
特に、追加するものに興味がありますelasticity
。
編集:
また、別の方法で移動することもできます。非常に基本的なダイナミクス システムから始めて、問題が再現できるようになるまでコンポーネントを追加します。たとえば、次の例は非常に迅速に収束します (「一時停止」のログ)。
@interface PTLViewController () <UIDynamicAnimatorDelegate>
@property (nonatomic, strong) UIDynamicAnimator *animator;
@end
@implementation PTLViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(100,100,100,100)];
view.backgroundColor = [UIColor lightGrayColor];
[self.view addSubview:view];
self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
self.animator.delegate = self;
UICollisionBehavior *collisionBehavior = [[UICollisionBehavior alloc] initWithItems:@[view]];
collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
[self.animator addBehavior:collisionBehavior];
UIGravityBehavior *gravityBehavior = [[UIGravityBehavior alloc] initWithItems:@[view]];
[self.animator addBehavior:gravityBehavior];
}
- (void)dynamicAnimatorDidPause:(UIDynamicAnimator *)animator {
NSLog(@"pause");
}
@end
すべてのアイテムの速度を取得することについてのあなたの質問に対して、私はそれを行う簡単な方法を知りません. 残念ながら、UIDynamicAnimator
すべてのアイテムを直接知っているわけではありません。プロパティUIDyanamicBehavior
が含まれていないため、これは間接的です。items
これが私と同じくらい気になる場合は、レーダー://15054405 を複製することを検討してください。
ただし、特定のアイテムの現在の線速度を知りたいだけの場合は、解決策があります。UIDynamicItemBehavior
ログに記録するカスタム アクションを追加するだけです。
UIDynamicItemBehavior *dynamicItemBehavior = [[UIDynamicItemBehavior alloc] initWithItems:@[view]];
__weak UIDynamicItemBehavior *weakBehavior = dynamicItemBehavior;
dynamicItemBehavior.action = ^{
NSLog(@"Velocity: %@", NSStringFromCGPoint([weakBehavior linearVelocityForItem:view]));
};
[self.animator addBehavior:dynamicItemBehavior];