问题
Goal:
Have several animations play at the same time on a single UIView.
Problem:
From what I can tell, this is not possible. Each animation has to occur in sequence and cannot overlap.
In essence, I want a single UIView to animate vertically while animating horizontally at the same time. Since I'm using UIViewAnimationOptionRepeat, I cannot nest any other animation in onCompletion: Here's what I want to work but doesn't:
[UIView animateWithDuration:duration
delay:kANIMATION_DELAY
options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse animations:^{
object.frame = CGRectMake(object.frame.origin.x + 40,
object.frame.origin.y,
object.frame.size.width,
object.frame.size.height);
[UIView animateWithDuration:duration
delay:kANIMATION_DELAY
options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse animations:^{
object.frame = CGRectMake(object.frame.origin.x,
object.frame.origin.y - 40,
object.frame.size.width,
object.frame.size.height);
} completion:^(BOOL finished) {
}];
} completion:^(BOOL finished) {
}];
回答1:
The answer is not to use UIViewAnimation blocks but instead CABasicAnimations. With them you can manipulate the center coordinate (x,y) separately. Here's what my code looks like now:
UIView *view = views[i];
// Add the horizontal animation
CABasicAnimation *horizontal = [CABasicAnimation animationWithKeyPath:@"position.x"];
horizontal.delegate = self;
horizontal.fromValue = [NSNumber numberWithFloat:25.0];
horizontal.toValue = [NSNumber numberWithFloat:50.0];
horizontal.repeatCount = INFINITY;
horizontal.duration = 6;
horizontal.autoreverses = YES;
horizontal.beginTime = 0; // ignore delay time for now
horizontal.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[view.layer addAnimation:horizontal forKey:@"horizontal_animation"];
// Add the vertical animation
CABasicAnimation *vertical = [CABasicAnimation animationWithKeyPath:@"position.y"];
vertical.delegate = self;
vertical.fromValue = [NSNumber numberWithFloat:100.0];
vertical.toValue = [NSNumber numberWithFloat:400.0];
vertical.repeatCount = INFINITY;
vertical.duration = 2;
vertical.autoreverses = YES;
vertical.beginTime = 0; // ignore delay time for now
vertical.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
[view.layer addAnimation:vertical forKey:@"vertical_animation"];
This allows me to handle repeat, duration, etc. in two separate animations. Then, when my animations are over, I can just call the follow method to remove animations. Either,
[view.layer removeAllAnimations];
or, if I want a more specific animation removed,
[view.layer removeAnimationForKey:@"vertical_animation"];
Then, if you want to some more custom control over when the animation starts/stops, you just need to add the delegate methods like so:
-(void)animationDidStart:(CAAnimation *)anim {
// custom code here
}
-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
// custom code here
}
It's pretty sweet and easy. Hope this helps anyone in a similar need. Cheers!
来源:https://stackoverflow.com/questions/21036434/multiple-simultaneous-uiviewanimations-on-a-single-uiview