1

でビューの回転を手動で変更しようとしていますUIDynamicsが、更新後にビューの回転が常にリセットされます。ドキュメントによると、そのメソッドはアイテム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.削除された動作をアニメーターに戻します (新しい動作を作成する必要はありませ

)すべてのビヘイビアーを 1 つの親ビヘイビアーに子ビヘイビアーとして追加できるため、一度にすべてのビヘイビアーを削除して戻すことができます (ただし、この態度は動的アニメーターのすべての動きを停止するため、害の少ない他の方法も検討する必要があります)。

- (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 に答える