iOS:UIDynamicAnimator updateItemUsingCurrentState 不适用于旋转
Posted
技术标签:
【中文标题】iOS:UIDynamicAnimator updateItemUsingCurrentState 不适用于旋转【英文标题】:iOS: UIDynamicAnimator updateItemUsingCurrentState not working with rotation 【发布时间】:2014-09-03 11:52:03 【问题描述】:我正在尝试手动更改 UIDynamics
中视图的旋转,但视图的旋转总是在更新后重置。 documentation 表示,UIDynamicAnimator
的 updateItemUsingCurrentState:
方法应该更新项目的位置和旋转,但只更新位置。
我创建了一个简短的示例,其中一个方形视图从屏幕上落下,触摸后它应该定位到触摸的位置并旋转 45 度。但是,不会发生旋转(有时旋转可以在几分之一秒内看到,但之后会再次重置):
#import "ViewController.h"
@interface ViewController ()
UIDynamicAnimator* _animator;
UIView* _square;
@end
@implementation ViewController
- (void)viewDidLoad
[super viewDidLoad];
_square = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
_square.backgroundColor = [UIColor grayColor];
[self.view addSubview:_square];
_animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
UIGravityBehavior *gravityBehavior = [[UIGravityBehavior alloc] initWithItems:@[_square]];
gravityBehavior.magnitude = 0.1;
[_animator addBehavior:gravityBehavior];
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
UITouch *touch = [[event allTouches] anyObject];
_square.center = [touch locationInView:self.view];
NSLog(@"transform before rotation: %@", NSStringFromCGAffineTransform(_square.transform));
_square.transform = CGAffineTransformMakeRotation(M_PI/4);
[_animator updateItemUsingCurrentState:_square];
NSLog(@"transform after rotation: %@", NSStringFromCGAffineTransform(_square.transform));
@end
(我将所有代码都保留在这里,以便您可以将其复制粘贴到新创建的项目中。希望没有太多不相关的代码造成干扰)
那么我做错了吗?还是不能显式更改视图的旋转?
【问题讨论】:
【参考方案1】:根据 Infinity James 的回答,我找到了一个效果很好的解决方案。 因此,要更新项目的轮换,您需要 1. 从动态动画师中移除所有影响项目的行为 2. 更新物品的旋转 3. 将删除的行为返回给动画师(无需创建新行为)注意:您可以将所有行为添加到一个父行为中作为子行为,这样您就可以立即删除并返回所有它们(但是这种态度会阻止动态动画师的所有运动,因此您还应该考虑其他危害较小的方式)。
- (void)rotateItem:(UICollectionViewLayoutAttributes *)item toAngle:(CGFloat)angle
CGPoint center = item.center;
[self.dynamicAnimator removeBehavior:self.parentBehavior];
item.transform = CGAffineTransformMakeRotation(angle);
[self.dynamicAnimator addBehavior:self.parentBehavior];
这个解决方案是一种妥协,因为它会停止物品的移动,所以如果你发现更好的东西,请添加你的答案......
【讨论】:
真好! updateItemUsingCurrentState 对此不起作用,这很糟糕【参考方案2】:我的解决方案是从动画师中删除行为,然后使用项目的修改状态重新创建行为。显式设置项目的位置(通过center
)和旋转并不是真正应该在 UIDynamics 的影响下完成的事情(就像在酒精的影响下,但更无聊)。
我的解决方案代码:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
[self.animator removeBehavior:self.gravityBehavior];
self.gravityBehavior = nil;
UITouch *touch = touches.anyObject;
CGPoint touchLocation = [touch locationInView:touch.view];
self.square.center = touchLocation
self.square.transform = CGAffineTransformMakeRotation(M_PI/4);
self.gravityBehavior = [[UIGravityBehavior alloc] initWithItem:self.square];
self.gravityBehavior.magnitude = 0.1f;
[self.animator addBehavior:self.gravityBehavior];
【讨论】:
感谢您的回答。但是,我的最终目的是定期(非常快,可能使用 UIDynamicBehavior 的动作块)增加多个项目的旋转,每个项目有 5 个行为,因为我希望它们在一段时间后不会停止移动。我不认为一直重现所有行为是明智的。但我会试一试,让你知道它是否能流畅运行。 是的,这不起作用,因为它会阻止正方形的移动。顺便说一句,如果不建议显式设置项目的位置和旋转,为什么还要存在 updateItemUsingCurrentState: 方法?以上是关于iOS:UIDynamicAnimator updateItemUsingCurrentState 不适用于旋转的主要内容,如果未能解决你的问题,请参考以下文章
UIDynamicAnimator items(in:) 在 iOS 11 中崩溃
iOS 使用 UIDynamicAnimator 进行视图控制器转换时如何计算转换持续时间?
UIDynamicAnimator + 自定义 UICollectionViewLayout 导致永久圆周运动