CABasicAnimation не имеет никакого эффекта

#objective-c #cocoa #core-animation

#цель-c #какао #ядро-анимация

Вопрос:

У меня возникла очень простая проблема, и я рву на себе волосы из-за нее. Я пытаюсь анимировать перемещение кнопки NSButton. Теперь я осознаю почти чрезмерно простую:

 [[button animator] setFrame:newCGRect];
 

Тем не менее, я хотел бы увеличить время, необходимое для перемещения кнопки. Итак, я изучил немного более сложную кабасическую анимацию. Я думаю, что я все делаю правильно, но кнопка NSButton вообще не двигается.

 CGPoint center = CGPointMake(10, 20);

CALayer *layer = button.layer;

layer.position = CGPointMake(button.frame.size.width / 2, button.frame.size.height / 2);

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
animation.fromValue = [layer valueForKey:@"position"];
[animation setToValue:[NSValue valueWithPoint:center]];
[animation setFillMode:kCAFillModeForwards];
[animation setRemovedOnCompletion:NO];
[animation setDuration:3.0];

[layer addAnimation:animation forKey:@"position"];
 

Здесь кнопка — это кнопка NSButton. Я устанавливаю положение слоя в центре кнопки, потому что я думаю, что «положение» должно относиться к центру. Затем все, что я делаю, это перемещаю (предположительно) кнопку в центр в анимации продолжительностью 3 секунды. Я добавляю анимацию к слою, а затем ничего не происходит.

Итак, кто-нибудь знает, что я делаю не так? Или, кстати, можно ли в любом случае использовать свойство animator и задать длину анимации?

Ответ №1:

Оберните неявную анимацию в транзакцию, чтобы настроить анимацию.

 [CATransaction begin];
[CATransaction setAnimationDuration:3];
[[button animator] setFrame:newframe];
[CATransaction commit];
 

Комментарии:

1. Большое вам спасибо, но я уже придумал ответ. Для справки, ваш ответ немного неточен, так как он анимирует, но не соблюдает заданную продолжительность. Это связано с тем, что при использовании CATransaction вы можете изменять только CALayer, а не подкласс NSView. Смотрите Мой ответ для получения более подробной информации.

Ответ №2:

Оказывается, мой исходный код был излишним, и ответ Джейсона Харвига ниже был более точным. Единственная проблема заключалась в том, что он не анимировался с заданной продолжительностью при анимации подкласса NSView (в данном случае NSButton). Чтобы исправить это, вот следующий код, который анимируется с заданной продолжительностью:

 [NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration:8];
[[button animator] setFrame:newRect];  
[NSAnimationContext endGrouping];
 

Комментарии:

1. Итак, если это решит вашу проблему, это не только нормально, но даже желательно, чтобы вы приняли свой собственный ответ, чтобы люди могли легко увидеть правильный ответ с первого взгляда. Посмотрите, как работает принятие ответа?

2. Я был бы рад принять это, но, учитывая, что у меня меньше 100 очков репутации, мне придется подождать два дня (сейчас уже один день), чтобы сделать это.