When programming for iOS, I frequently find myself faced with the following situation:
- (void)someMethod
{
[self performSomeAnimation];
//below is an action I want to perform, but I want to perform it AFTER the animation
[self someAction];
}
- (void)performSomeAnimation
{
[UIView animateWithDuration:.5 animations:^
{
//some animation here
}];
}
Faced with this situation, I usually end up just copy/pasting my animation code so that I can use the completion block handler, like so:
- (void)someMethod
{
[self performSomeAnimation];
//copy pasted animation... bleh
[UIView animateWithDuration:.5 animations:^
{
//same animation here... code duplication, bad.
}
completion^(BOOL finished)
{
[self someAction];
}];
}
- (void)performSomeAnimation
{
[UIView animateWithDuration:.5 animations:^
{
//some animation here
}];
}
What is the proper way to solve this problem? Should I be passing a block of code to my -(void)performSomeAction method, like below, and executing that block on completion of the animation?
- (void)someMethod
{
block_t animationCompletionBlock^{
[self someAction];
};
[self performSomeAnimation:animationCompletionBlock];
}
- (void)performSomeAnimation:(block_t)animationCompletionBlock
{
[UIView animateWithDuration:.5 animations:^
{
//some animation here
}
completion^(BOOL finished)
{
animationCompletionBlock();
}];
}
Is that the proper way to solve this problem? I guess I have been avoiding it because I’m not THAT familiar with block usage (not even sure if I declared that block properly) and it seems like a complicated solution to a simple problem.
You could also do this:
And instead of explicitly defining a block and passing it as parameter, you can call it directly like this (this is how block animations work for UIView, for example):