Reputation: 1117
I have four UIbuttons and I have to change their x origin. By now I am using this method:
[UIView animateWithDuration:1.0
delay:1.0
options: UIViewAnimationCurveEaseInOut
animations:^{
self.Button1.frame = CGRectMake(-120, self.Button1.frame.origin.y, self.Button1.frame.size.width, self.Button1.frame.size.height);
}
completion:^(BOOL finished){
[UIView animateWithDuration:1.0
delay:1.0
options: UIViewAnimationCurveEaseInOut
animations:^{
self.Button1.frame = CGRectMake(-140, self.Button1.frame.origin.y, self.Button1.frame.size.width, self.Button2.frame.size.height);
}
completion:^(BOOL finished){
}];
}];
I am putting one animation in the completition section of the next. But I have 4/5 buttons. I can't do this so many times. Is there a way to do an animation on an object, and after a delay of 0.5 seconds do it on the next?
EDIT:
I tried to use this:
typedef void (^AnimationBlock)();
AnimationBlock firstAnimation = ^{ self.Button1.frame = CGRectMake(-120, self.Button1.frame.origin.y, self.Button1.frame.size.width, self.Button1.frame.size.height); };
AnimationBlock secondAnimation = ^{ self.Button4.frame = CGRectMake(-120, self.Button4.frame.origin.y, self.Button4.frame.size.width, self.Button4.frame.size.height);};
[UIView animateWithDuration:2 animations:firstAnimation completion:^(BOOL finished) {
[UIView animateWithDuration:2 animations:secondAnimation];
}];
but there is no possibility to set the time between the two animations.
Upvotes: 3
Views: 230
Reputation: 17364
Do something like this (in this example I'm moving the same UIButton in all animations because I tried first on XCode, but you can change the content of the animation blocks as you prefer)
typedef void (^AnimationBlock)();
// declare two example animations
AnimationBlock firstAnimation = ^{
CGRect firstFrame = self.aButton.frame;
firstFrame.origin.x = firstFrame.origin.x - 20;
self.aButton.frame = firstFrame;
};
AnimationBlock secondAnimation = ^{
CGRect firstFrame = self.aButton.frame;
firstFrame.origin.x = firstFrame.origin.x - 20;
self.aButton.frame = firstFrame;
};
// starting point, create an array of animations
NSArray *animations = @[firstAnimation, secondAnimation];
// first animation starts immediately
double delayInSeconds = 0.0;
for (AnimationBlock animation in animations) {
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[UIView animateWithDuration:0.5f animations:[animation copy]];
});
// first animation starts immediately, then increase the dispatch_after timer of 0.5 sec at each loop
delayInSeconds = delayInSeconds + 0.5f;
}
Essentially:
Upvotes: 1
Reputation: 13276
What I would do is just take the code you have and make it more generic. Then you can simply animate any button with any delay.
- (void)animateButton:(UIButton *)button toRect:(CGRect)rect1 thenToRect:(CGRect)rect2 withDelay:(CGFloat)delay
{
[UIView animateWithDuration:1.0
delay:delay
options:UIViewAnimationCurveEaseInOut
animations:^{
button.frame = rect1;
}
completion:^(BOOL finished){
[UIView animateWithDuration:1.0
delay:delay
options:UIViewAnimationCurveEaseInOut
animations:^{
button.frame = rect2;
}
completion:nil];
}];
}
Then you use it like this (I simplified the rect creation code to make it cleaner)
[self animateButton:self.button1
toRect:CGRectOffset(self.button1.frame, -120 - self.button1.frame.origin.x)
thenToRect:CGRectOffset(self.button1.frame, -140 - self.button1.frame.origin.x)
delay:0.5f];
Upvotes: 2