I have the following simple UIImageView animation:
-(void) setupTheAnimation {
self.imgView.animationImages = imagesArr;
[self.imgView setAnimationRepeatCount:-1];
self.imgView.animationDuration =0.9;
[self.imgView startAnimating];
[self performSelector:@selector(stopTheAnimation) withObject:nil afterDelay:4.0];
}
-(void) stopTheAnimation {
[self.imgView stopAnimating];
}
but I face a problem when the animation stops I do not know what is the last frame it stops at !! so the ending of animation is not smooth at all.
so I need to:
1) know what is the last frame at which the animation ends, so I set it as the last image of the animation and this leads to a smooth stopping.
2) stop this animation gradually, i.e. changing its duration time before it stops to slow it down first then stop it.
This is a link to the sample project.
I know your original implementation uses animationImages
, but I don't know of a way to use animationImages
directly with a continuously variable duration. However, this is a pretty simple feature to implement yourself. If you do so, then you can code a dynamic duration value between images in your array.
In the following code, I replace animationImages
with a custom stepping function, and dynamically adjust the duration after a stop has been requested. Take note that this is a little different than your original code, that specified a hard end time. This code specifies when the gear spin should start slowing down.
If you really have a hard animation period, you can adjust the call to stopTheAnimation
to account for the deceleration factor you choose (I simply increase the duration by 10% per step, during deceleration, until the steps are slower than a given threshold value):
// my animation stops when the step duration reaches this value:
#define STOP_THRESHOLD_SECONDS 0.1f
#define NUM_IMAGES 35
@implementation ViewController
{
NSMutableArray *imagesArr;
int currentImage;
BOOL stopRequested;
NSTimeInterval duration;
}
-(void) setupTheAnimation {
stopRequested = NO;
currentImage = 0;
duration = 0.9f / NUM_IMAGES;
[self stepThroughImages];
[self performSelector:@selector(stopTheAnimation) withObject:nil afterDelay:4.0];
}
- (void) stepThroughImages {
self.imgView.image = [imagesArr objectAtIndex: currentImage];
if (currentImage == NUM_IMAGES - 1) {
currentImage = 0;
} else {
currentImage++;
}
if (stopRequested && duration < STOP_THRESHOLD_SECONDS) {
// we're slowing down gradually
duration *= 1.1f;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(duration * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self stepThroughImages];
});
} else if (!stopRequested) {
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(duration * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self stepThroughImages];
});
}
}
-(void) stopTheAnimation {
stopRequested = YES;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With