iOS:UIDynamicAnimator updateItemUsingCurrentState 不适用于旋转

Posted

技术标签:

【中文标题】iOS:UIDynamicAnimator updateItemUsingCurrentState 不适用于旋转【英文标题】:iOS: UIDynamicAnimator updateItemUsingCurrentState not working with rotation 【发布时间】:2014-09-03 11:52:03 【问题描述】:

我正在尝试手动更改 UIDynamics 中视图的旋转,但视图的旋转总是在更新后重置。 documentation 表示,UIDynamicAnimatorupdateItemUsingCurrentState: 方法应该更新项目的位置和旋转,但只更新位置。 我创建了一个简短的示例,其中一个方形视图从屏幕上落下,触摸后它应该定位到触摸的位置并旋转 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 导致永久圆周运动

减慢 UIDynamicAnimator 的动画

为啥我的 UIDynamicAnimator 类继承不能使用 addChildBehavior

IOS7笔记-8协议block动画