所以这就是我想要做的,我希望有一个动画队列发生。这些不能同时发生,因为这会破坏效果,只显示队列中的最后一个动画。如何在开始新动画之前创建一个等待上一个动画完成的队列(在Swift中)?
以下仅显示xpItems数组中的最终动画。</ p>
var xpItems = XPItem.loadCustomObjectWithKey()
for (var i = 0; i < xpItems.count; i++) { //for each XP Item.
let rewardName = xpItems[i].title
let rewardAmount = xpItems[i].xpAmount
println(rewardName + " " + String(rewardAmount))
let currentLevelXPRequired = 100
let newProgress = CGFloat(rewardAmount) / CGFloat(currentLevelXPRequired) as CGFloat
self.xpCircle.setProgress(xpCircle.progress + newProgress, animated: true)
}
//其余代码是Obj-c。
- (void)setProgress:(CGFloat)progress animated:(BOOL)animated
{
if (self.progress == progress) {
return;
}
if (animated == NO) {
if (_displayLink) {
//Kill running animations
[_displayLink removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
_displayLink = nil;
}
[self setNeedsDisplay];
} else {
_animationStartTime = CACurrentMediaTime();
_animationFromValue = self.progress;
_animationToValue = progress;
if (!_displayLink) {
//Create and setup the display link
[self.displayLink removeFromRunLoop:NSRunLoop.mainRunLoop forMode:NSRunLoopCommonModes];
self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(animateProgress:)];
[self.displayLink addToRunLoop:NSRunLoop.mainRunLoop forMode:NSRunLoopCommonModes];
} /*else {
//Reuse the current display link
}*/
}
}
- (void)animateProgress:(CADisplayLink *)displayLink
{
dispatch_async(dispatch_get_main_queue(), ^{
CGFloat dt = (displayLink.timestamp - _animationStartTime) / self.animationDuration;
if (dt >= 1.0) {
//Order is important! Otherwise concurrency will cause errors, because setProgress: will detect an animation in progress and try to stop it by itself. Once over one, set to actual progress amount. Animation is over.
[self.displayLink removeFromRunLoop:NSRunLoop.mainRunLoop forMode:NSRunLoopCommonModes];
self.displayLink = nil;
[super setProgress:_animationToValue animated:NO];
[self setNeedsDisplay];
return;
}
//Set progress
[super setProgress:_animationFromValue + dt * (_animationToValue - _animationFromValue) animated:YES];
[self setNeedsDisplay];
});
}
super.setProgress [..]:
- (void)setProgress:(CGFloat)progress animated:(BOOL)animated
{
_progress = progress;
}
很抱歉让代码在obj-c / swift中。
答案 0 :(得分:4)
大多数动画方法,当然在UIKit中都有一个完成处理程序,可以在动画完成时自动调用。您需要做的就是创建一个UIView
s或其他对象的数组,然后您可以在其上执行动画(可能是CGPoint
的数组),然后按顺序为所有对象设置动画。 E.g:
- (void)animateArrayWithCompletion:(void(^)(void))handler
{
if (!viewArray.count) {
if (handler) {
handler();
}
}
else {
UIView *myView = viewArray.lastObject;
[viewArray removeObject:myView];
CGRect frame = myView.frame;
frame.origin.x += 100;
[UIView animateWithDuration:1 animations:^{
myView.frame = frame;
} completion:^(BOOL complete) {
[self animateArrayWithCompletion:handler];
}];
}
}