你是正确的,一旦一切都停止,动画师应该暂停。
检查items
与您的重力行为相关的内容,并确保没有其他物品仍在下落。例如,很容易意外创建以下错误:
- 为重力和碰撞添加视图
- 从超级视图和碰撞中删除视图
- 无法从重力中移除视图
在这种情况下,“鬼物”将永远陨落。
另一个可能的问题(尽管根据您的描述不太可能)是您的项目是否附加到导致无限但小的“反弹”的其他行为。我会检查你的动画师的完整行为列表(记得检查孩子的行为)。特别是我会对任何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
属性。如果这让您和我一样困扰,请考虑复制radar://15054405。
但是,如果您只想知道特定项目的当前线速度,则有一个解决方案。只需添加一个UIDynamicItemBehavior
自定义操作来记录它:
UIDynamicItemBehavior *dynamicItemBehavior = [[UIDynamicItemBehavior alloc] initWithItems:@[view]];
__weak UIDynamicItemBehavior *weakBehavior = dynamicItemBehavior;
dynamicItemBehavior.action = ^{
NSLog(@"Velocity: %@", NSStringFromCGPoint([weakBehavior linearVelocityForItem:view]));
};
[self.animator addBehavior:dynamicItemBehavior];