gpt4 book ai didi

ios - 当 UIGravityBehavior 处于事件状态时,UIDynamicAnimator 拒绝达到平衡

转载 作者:技术小花猫 更新时间:2023-10-29 11:22:00 26 4
gpt4 key购买 nike

我正在编写可扩展托盘 View 的代码,它使用 UIDynamicAnimator 来实现漂亮的展开/收缩动画。

为了实现逼真的加速,我使用 UIGravityBehavior 让我的托盘掉落,直到托盘的“标签”触及屏幕底部。

这很好用,但即使场景中的所有项目都停止移动,也永远不会调用 UIDynamicAnimatorDelegate dynamicAnimatorDidPause:。这意味着动画师继续使用 CPU 周期为场景设置动画(委托(delegate)已设置,并为 UIDynamicAnimatorDelegate dynamicAnimatorDidPause: 触发)。

我尝试从场景中移除 UIGravityBehavior,这确实导致动画师最终停止。不过,我无法正确安排移除重力行为的时间,因为我需要在一切都停止移动后将其从场景中移除。

我知道重力是一种恒定的力,但我仍然认为一旦一切都具有 0 速度和 0 加速度,它就会停止动画师。

最后一个假设是错误的吗?

有人遇到类似的问题吗?

最佳答案

你说得对,动画师应该在一切静止后暂停。

检查哪些 items 附加到您的重力行为,并确保没有其他项目仍在下落。例如,很容易不小心造成以下错误:

  • 添加重力和碰撞 View
  • 从父 View 和碰撞中移除 View
  • 无法从重力中移除 View

在这种情况下,“幽灵元素”将永远掉落。

另一个可能的问题(虽然根据您的描述不太可能)是如果您的项目附加到导致无限但小的“反弹”的其他行为。我会检查你的动画师的完整行为列表(记得也要检查 child 的行为)。特别是,我会对添加 elasticity 的任何 UIDynamicItemBehavior 感兴趣。


编辑:

您可能还想走另一条路。从一个非常基本的动力学系统开始,然后添加您自己的组件,直到您可以重现问题。例如,以下确实很快收敛(记录“暂停”):

@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];

关于ios - 当 UIGravityBehavior 处于事件状态时,UIDynamicAnimator 拒绝达到平衡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19385003/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com