Как я запускаю обратный вызов, когда NSAnimationContext заканчивается? - PullRequest
3 голосов
/ 01 декабря 2008

У меня есть анимация, которая перемещает некоторые виды вокруг. Когда анимация завершится, я хочу, чтобы окно пересчитало цикл просмотра ключей. Мой код похож на следующий код:

[NSAnimationContext beginGrouping];        
[newView setAlpha: 0.0]; //hide newView
[self addSubView:newView];

//position the views
[[oldView animator] setFrame: newFrame1];
[[newView animator] setFrame: newFrame2];

[[newView animator] setAlpha: 1.0]; //fade-in newView

[NSAnimationContext endGrouping]; 

[[self window] recalculateKeyViewLoop];

Проблема с этим кодом заключается в том, что recalculateKeyViewLoop вызывается до того, как представления заняли свои новые позиции, что означает, что keyviewloop неправильный.

Как мне это исправить?

Сначала я должен вызвать recalculateKeyViewLoop в обратном вызове, когда анимация заканчивается, но я не могу понять, как это сделать.

Ответы [ 6 ]

5 голосов
/ 02 декабря 2008

Что-то не столь очевидное или, по крайней мере, для меня, это то, что при выполнении setFrame: происходит две анимации с клавишами frameSize и frameOrigin.

.

В зависимости от того, какие у вас исходные и конечные кадры, вам может потребоваться зарегистрироваться в качестве делегата для одного или обоих из них.

Я бы также порекомендовал вам сделать копию анимации, которую вы получили из -animationForKey:, и сохранить вашу измененную копию в словаре animations вашего объекта. Таким образом, ваш делегат будет вызываться только по окончании продолжительности анимации этого конкретного объекта, по сравнению со всеми объектами, оживляющими этот ключ.

например.

CAAnimation *animation = [[view animationForKey:@"frameOrigin"] copy];
animation.delegate = self;
[view setAnimations:[NSDictionary dictionaryWithObject:animation forKey:@"frameOrigin"]];

Таким образом, ваш объект анимации заменит объект анимации по умолчанию для этого представления. Затем реализуйте те методы делегирования, которые вас интересуют.

4 голосов
/ 01 декабря 2008

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

1 голос
/ 10 июля 2013

Вы можете использовать обработчик завершения следующим образом:

[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context){
    // Start some animations.
    [[myView animator] setFrameSize:newViewSize];
    [[myWindow animator] setFrame:newWindowFrame display:YES];
} completionHandler:^{
    // This block will be invoked when all of the animations started above have completed or been cancelled.
    NSLog(@"All done!");
}];
1 голос
/ 01 декабря 2008

если вы используете CAAnimation, он имеет метод animationDidStop: закончен: делегат ..

http://developer.apple.com/documentation/GraphicsImaging/Reference/CAAnimation_class/Introduction/Introduction.html#//apple_ref/occ/cl/CAAnimation

Надеюсь, это поможет

0 голосов
/ 04 марта 2013

Если вы анимируете NSWindow (в отличие от NSView), другие ответы не будут работать, и вы должны сделать это вместо этого:

CAAnimation *animation = [CABasicAnimation animation];
animation.delegate = self;
self.window.animations = @{@"frame": animation};
[[self.window animator] setFrame:NSMakeRect(0, 0, 400, 200) display:YES];

, который затем вызовет метод animationDidStop:finished: для вашего делегата (который в приведенном выше коде будет self)

0 голосов
/ 27 октября 2011

Проверьте мой пост здесь: Как бы я сделал эту iOS-анимацию на OSX?

Я написал класс, который обрабатывает это для вас, используя блоки. Надеюсь, ваша цель позволяет блокировать! :)

...