2014-09-03 2 views
1

Я пытаюсь вручную изменить поворот вида в UIDynamics, но вращение представления всегда сбрасывается после обновления. В документе documentation говорится, что метод UIDynamicAnimator updateItemUsingCurrentState: должен обновлять положение и поворот элемента, но обновляется только позиция.
Я создал короткий пример, где квадратный снимок падает с экрана, и после касания он должен быть расположен к месту касания и повернут на 45 градусов. Однако вращение не происходит (иногда вращение можно увидеть в течение доли секунды, но после этого он снова сбрасывается):iOS: UIDynamicAnimator updateItemUsingCurrentState не работает с вращением

#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 

(я оставил здесь весь код, так что вы можете авторские вставьте его во вновь созданный проект. Надеюсь, не слишком много нерелевантного кода, чтобы он был тревожным).

Так что я делаю что-то не так? Или не удается явно изменить поворот представления?

ответ

5

на основе ответа от Infinity Джеймса я нашел решение, которое работает достаточно хорошо. Таким образом, чтобы обновить вращение по элементу необходимо
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]; 
} 

Это решение является своего рода компромиссом, так как он останавливает движение элемента, поэтому, пожалуйста, добавить свой ответ, если вы найдете что-то лучше ...

+0

Сладкий! Это неудобно, что updateItemUsingCurrentState не работает для этого – marchinram

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]; 
} 
+0

спасибо за ваш ответ. однако моя конечная цель - периодически (довольно быстро, возможно, используя блок действий UIDynamicBehavior) увеличивать вращение нескольких элементов с 5 поведением на каждом из них, потому что я хочу, чтобы они не переставали двигаться через некоторое время. Я не думаю, что было бы разумно воссоздать все поведенческие действия все время. Но я попробую и дам вам знать, работает ли он плавно. –

+0

Да, это не сработает, потому что оно останавливает движение квадрата. Кстати, почему бы существовать метод updateItemUsingCurrentState: если явно не было указано положение и поворот позиции, это не рекомендуется? –