More specifically I have a UIScrollView
with an embedded UIImageView
.
I have an object which describes an "animation" frame
@class AnimationFrame
@property (nonatomic,strong) UIImage *image;
@property (nonatomic) CGRect zoomToRectInImage;
@property (nonatomic) CGFloat duration;
@end
I would like to chain the frames to each other such that the imageview will swap the current image to the animationframe.image
and then zoom to that position.
I thought about doing something like this (pseudo code):
-(void)animateImageView
{
// imagine these were created before hand
NSArray *myAnimationFrames = @[frame1,frame2,frame3,frame4,frame5];
// now iterate through the frames and start the animation
for (AnimationFrame *frame in myAnimationFrames)
{
self.scrollview.zoomScale = 1.0;
self.imageView.image = frame.image;
[self.scrollview zoomToRect:frame.zoomToRectInImage animated:YES];
}
}
But I'm having trouble synchronizing between the image changes and zooming.
How can I make sure they are not overlapping?
If your array of frames are dynamic, or the array becomes large, the task continuation becomes a bit unwieldy to implement.
With a help of a third party library (well, just one class) it can look like this:
First, define an animation task as follows:
Then, assuming you implemented a category for NSArray:
You can run your frames as follows:
If you want to cancel the animations before all finished:
The implementation of the category is shown below. Note, this is a generic implementation, it simply serially invokes the asynchronous function specified by a block task for each element in the array in order. So, this is a tool which can be reused elsewhere, too - not just for performing animations.
RXPromise is available at GitHub: RXPromise. Disclosure: I'm the author.