1

我正在尝试手动更改UIDynamics视图的旋转,但视图的旋转总是在更新后重置。文档说, that的方法应该更新项目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

(我把所有的代码都留在这里了,这样你就可以把它复制粘贴到一个新创建的项目中。希望没有太多不相关的代码让人不安)

那我做错了吗?或者是否可以显式更改视图的旋转?

4

2 回答 2

5

根据 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];
}

这个解决方案是一种妥协,因为它会停止项目的移动,所以如果你发现更好的东西,请添加你的答案......

于 2014-09-09T13:50:49.833 回答
1

我的解决方案是从动画师中删除行为,然后使用项目的修改状态重新创建行为。显式设置项目的位置(通过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];
}
于 2014-09-05T12:12:28.440 回答