我在动画方面遇到了一些问题。这是我想要做的。 首先,我有一个 for 循环,我在其中制作一些UILabels的动画,例如
label1.frame = CGRectMake(xBoard, 5, textWidth, term1Label.frame.size.height);
xBoard = xBoard + textWidth;
label1.textColor = term1Label.textColor;
label1.font = [UIFont italicSystemFontOfSize:textHeight];
label1.textAlignment = term1Label.textAlignment;
label1.text = label1String;
label1.alpha = 0;
label1.backgroundColor = [UIColor clearColor];
[boardView addSubview:label1];
[UIView animateWithDuration:2.0*time
delay:timeDelay
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
label1.alpha = 1;
} completion:^(BOOL finished){
}
];
timeDelay = timeDelay + 2.0*time;
有些标签出现,有些标签消失,有些变色。一切正常,直到我进行第二次循环。然后出现代码的第一部分(更改颜色的动画仍在工作,但第一个循环中的所有标签都是可见的,并且没有动画。第二个循环动画很好。
我试图用CABasicAnimations替换动画[UIView animateWithDuration:...]并将它们保存在一个带队列的NSMutableArray中,但我没有成功。可能我的知识太短暂了。欢迎任何帮助。谢谢!!!
答案 0 :(得分:0)
我正在解决我的问题。做我的循环我在表中保存动画参数
NSArray *animation1 = [[NSArray alloc]initWithObjects:[NSNumber numberWithInt:label1.tag], [NSNumber numberWithInt:3],[NSNumber numberWithFloat:0.5f*time],[NSNumber numberWithFloat:timeDelay],[NSNumber numberWithFloat:0],nil];
[animations addObject:animation1];
在虚空的最后我称之为[self performAnimations];
- (void)performAnimations {
if ([[self animations] count] == 0) return;
for (int i=0; i<[[self animations] count]; i++) {
int tag = [[[animations objectAtIndex:i]objectAtIndex:0]intValue];
int animation = [[[animations objectAtIndex:i]objectAtIndex:1]intValue];
float animTime = [[[animations objectAtIndex:i]objectAtIndex:2]floatValue];
float animDelay = [[[animations objectAtIndex:i]objectAtIndex:3]floatValue];
float parameter = [[[animations objectAtIndex:i]objectAtIndex:4]floatValue];
UILabel *label = [UILabel alloc];
UIView *view = [UIView alloc];
if ([[self.view viewWithTag:tag] isKindOfClass:[UILabel class]]){
label = (UILabel *)[self.view viewWithTag:tag];
} else if ([[self.view viewWithTag:tag] isKindOfClass:[UIView class]]) {
view = (UIView *)[self.view viewWithTag:tag];
}
switch (animation) {
case 1:
[PolyCalcsViewController colorizeLabelForAWhile:label withUIColor:[UIColor yellowColor] animated:YES withTime:animTime withDelay:animDelay];
break;
case 2:
[PolyCalcsViewController appear:label withTime:animTime withDelay:animDelay];
break;
case 3:
[PolyCalcsViewController disappear:label withTime:animTime withDelay:animDelay];
break;
case 4:
[PolyCalcsViewController moveView:view withOffset:parameter withTime:animTime withDelay:animDelay];
break;
default:
break;
}
}
[animations removeAllObjects];
}
+(void)colorizeLabelForAWhile:(UILabel *)label withUIColor:(UIColor *)tempColor animated:(BOOL)animated withTime:(float)time withDelay:(float)delay{
UILabel *tempLabel = [[UILabel alloc] init];
tempLabel.textColor = tempColor;
tempLabel.font = label.font;
tempLabel.alpha = 0;
tempLabel.textAlignment = label.textAlignment;
tempLabel.text = label.text;
tempLabel.backgroundColor = [UIColor clearColor];
[label.superview addSubview:tempLabel];
tempLabel.frame = label.frame;
if (animated) {
[UIView animateWithDuration:time
delay:delay
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
// Animate it
label.alpha = 0;
tempLabel.alpha = 1;
} completion:^(BOOL finished){
[UIView animateWithDuration:time
delay:0
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
// Animate it back.
label.alpha = 1;
tempLabel.alpha = 0;
} completion:^(BOOL finished){
// Remove the tempLabel view when we are done.
[tempLabel removeFromSuperview];
}];
}];
} else {
// Change it back at once and remove the tempLabel view.
label.alpha = 1.0;
[tempLabel removeFromSuperview];
}
}
+(void)appear:(UILabel *)label withTime:(float)time withDelay:(float)delay{
[UIView animateWithDuration:time
delay:delay
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
label.alpha = 1.0;
} completion:^(BOOL finished){
NSLog(@"Anim Appear %d",label.tag);
}];
}
+(void)disappear:(UILabel *)label withTime:(float)time withDelay:(float)delay{
[UIView animateWithDuration:time
delay:delay
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
label.alpha = 0.0;
} completion:^(BOOL finished){
NSLog(@"Anim Disappear %d",label.tag);
[label removeFromSuperview];
}];
}
关键是程序没有按顺序执行表格动画中的动画。我想我应该放弃时间延迟并在前一个动画结束时运行下一个动画。我可以在完成时创建一个计数器:( BOOL完成)块,但我不知道如何因为该函数不接受外部变量。任何想法如何检测动画结束并控制表执行?感谢。
答案 1 :(得分:0)
最后我解决了这个问题。这是一个正确工作的代码
- (void)performAnimations {
// Finish when there are no more animations to run
int i = animationNumber;
int tag = [[[animations objectAtIndex:i]objectAtIndex:0]intValue];
int animation = [[[animations objectAtIndex:i]objectAtIndex:1]intValue];
float animTime = [[[animations objectAtIndex:i]objectAtIndex:2]floatValue];
//float animDelay = [[[animations objectAtIndex:i]objectAtIndex:3]floatValue];
float animDelay = 0;
float parameter = [[[animations objectAtIndex:i]objectAtIndex:4]floatValue];
UILabel *label = [UILabel alloc];
UIView *view = [UIView alloc];
if ([[self.view viewWithTag:tag] isKindOfClass:[UILabel class]]){
label = (UILabel *)[self.view viewWithTag:tag];
} else if ([[self.view viewWithTag:tag] isKindOfClass:[UIView class]]) {
view = (UIView *)[self.view viewWithTag:tag];
}
switch (animation) {
case 1:
[self colorizeLabelForAWhile:label withUIColor:[UIColor yellowColor] animated:YES withTime:animTime withDelay:animDelay];
break;
case 2:
[self appear:label withTime:animTime withDelay:animDelay];
break;
case 3:
[self disappear:label withTime:animTime withDelay:animDelay];
break;
case 4:
[self moveView:view withOffset:parameter withTime:animTime withDelay:animDelay];
break;
default:
break;
}
}
-(void)animationDidFinished{
animationNumber = animationNumber + 1;
if (animationNumber == [[self animations] count]) {
[animations removeAllObjects];
return;
} else {
[self performAnimations];
}
}
-(void)colorizeLabelForAWhile:(UILabel *)label withUIColor:(UIColor *)tempColor animated:(BOOL)animated withTime:(float)time withDelay:(float)delay{
UILabel *tempLabel = [[UILabel alloc] init];
tempLabel.textColor = tempColor;
tempLabel.font = label.font;
tempLabel.alpha = 0;
tempLabel.textAlignment = label.textAlignment;
tempLabel.text = label.text;
tempLabel.backgroundColor = [UIColor clearColor];
[label.superview addSubview:tempLabel];
tempLabel.frame = label.frame;
if (animated) {
[UIView animateWithDuration:time
delay:delay
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
// Animate it
label.alpha = 0;
tempLabel.alpha = 1;
} completion:^(BOOL finished){
[UIView animateWithDuration:time
delay:0
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
// Animate it back.
label.alpha = 1;
tempLabel.alpha = 0;
} completion:^(BOOL finished){
// Remove the tempLabel view when we are done.
[tempLabel removeFromSuperview];
if (finished) {
[self animationDidFinished];
}
}];
}];
} else {
// Change it back at once and remove the tempLabel view.
label.alpha = 1.0;
[tempLabel removeFromSuperview];
}
}
-(void)appear:(UILabel *)label withTime:(float)time withDelay:(float)delay{
[UIView animateWithDuration:time
delay:delay
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
label.alpha = 1.0;
} completion:^(BOOL finished){
NSLog(@"Anim Appear %d",label.tag);
if (finished) {
[self animationDidFinished];
}
}];
}
-(void)disappear:(UILabel *)label withTime:(float)time withDelay:(float)delay{
[UIView animateWithDuration:time
delay:delay
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
label.alpha = 0.0;
} completion:^(BOOL finished){
NSLog(@"Anim Disappear %d",label.tag);
[label removeFromSuperview];
if (finished) {
[self animationDidFinished];
}
}];
}
-(void)moveView:(UIView *)view withOffset:(float)offset withTime:(float)time withDelay:(float)delay{
[UIView animateWithDuration:time
delay:delay
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
CGRect frame = view.frame;
frame.origin.y += offset;
view.frame = frame;
} completion:^(BOOL finished){
if (finished) {
[self animationDidFinished];
}
}
];
}