我有路径存储在CGPoints数组中,我想移动图像。这是我到目前为止的一般代码:
-(void)movePic:(id)sender{
for(int i = 0; i < self.array.count; i++){
CGPoint location = [[self.array objectAtIndex:i] CGPointValue];
[UIView animateWithDuration:0.1 animations:^{
self.imageView.center = location;
} completion:^(BOOL finished){
}];
}
}
问题是for循环运行得非常快,所以你只能看到最后几点的动画。我不确定如何更好地设计这个。理想情况下,我可以做些什么来确保一个动画在另一个动画开始之前完成?我不应该使用for循环吗?感谢
答案 0 :(得分:4)
您的代码假定UIView动画在主线程中同步运行,而不是。
您似乎有两个选择
CAKeyframeAnimation
,可沿任意数量的采样点设置CALayer
动画(在它们之间进行插值)UIView
动画,用于沿着一系列采样点设置UIView
动画(在它们之间进行插值)前者会更有效率 - 我仍然认为我可以向你展示两种选择。
- (void)movePic:(id)sender
{
//create a mutable core-graphics path
CGMutablePathRef path = CGPathCreateMutable();
for(int i = 0; i < self.array.count; i++)
{
CGPoint location = [[self.array objectAtIndex:index] CGPointValue];
CGPathAddLineToPoint(path, nil, location.x, location.y);
}
//create a new keyframe animation
CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
//add our path to it
pathAnimation.path = path;
//be nice to the system
CGPathRelease(path);
//setup some more animation parameters
pathAnimation.duration = 0.1 * self.array.count;
//add the animation to our imageView's layer (which will start the animation)
[self.imageView.layer addAnimation:pathAnimation forKey:@"pathAnimation"];
}
- (void)movePicToPointAtIndex:(unsigned int)index
{
//safeguard check...
if ([self.array count] <= index)
return;
//get the next location
CGPoint location = [[self.array objectAtIndex:index] CGPointValue];
//animate the imageView center towards that location
[UIView animateWithDuration:0.1
delay:0.0
options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionAllowUserInteraction
animations:^{
self.imageView.center = location;
} completion:^(BOOL finished){
//we are done with that animation, now go to the next one...
[self movePicToPointAtIndex:index+1];
}];
}
- (void)movePic:(id)sender
{
[self movePicToPointAtIndex:0];
}
答案 1 :(得分:2)
好的,你要做的就是将点数组设置为类的属性,如animationPath
。好的,所以现在你必须注意UIView动画委托方法的委托方法(它实际上不是一个不同的类,它只是类'方法的委托)。
设置一个方法,每次动画停止时调用setAnimationDidStopSelector:selector
,所以在这里你会有这样的事情:
//Inside the callback for setAnimationDidStopSelector
if ([animationPath count] != 0){
//Go to next point
CGPoint location = [[self.array objectAtIndex:0] CGPointValue];
[UIView animateWithDuration:0.1 animations:^{
self.imageView.center = location;
} completion:^(BOOL finished){
}];
}
else{
NSLog(@"Nowhere else to go, animation finished :D");
}
因此,请务必使用第一点启动动画。
据我记得UIView
的动画管理其他线程中的内容,这可能就是for语句无效的原因。