Reputation:
I have 2 NSArrays. 1 - An array with images. and 2- An array with URLs.
What I want to do is transition through the array of images (3 sec. each) and when the user clicks on a specific image, I want the same index from the image clicked to access the url of that index.
For example: If the image at index 1 is currently showing, and the user clicks on that image (index 1) then I want the app to take you to the url at index 1.
Here is my code:
#import <QuartzCore/QuartzCore.h>
...
NSArray *images = [[NSArray alloc] initWithObjects: @"myimage1", @"myimage2", nil];
NSArray *urls = [[NSArray alloc] initWithObjects: @"www.google.com",
@"www.stackoverflow.com", nil];
imageView.image = [UIImage imageNamed:images];
CATransition *transition = [CATransition animation];
transition.duration = 3.0f;
transition.timingFunction = [CAMediaTimingFunction
functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionFade;
[imageView.layer addAnimation:transition forKey:nil];
I'm pretty new at this, so please don't be too harsh on me if something is not clear, or if the code doesn't make sense.
Thanks!
Upvotes: 0
Views: 335
Reputation: 131418
There are lots of ways to handle this.
You need to be clear about the behavior you want. Do you want it to do a 3 second fade from the first image to the next, and then immediately start fading to the next image in the sequence? If so, when the user clicks, how do you decide which animation is the current animation?
I would think it would be better to have an image hold at one image for most of your 3 seconds, and then have a transition period (1/2 second? 1 second?) where the cross-fade takes place. Then it would be clear that if the user clicks during the pause, the current image is the one who's URL is loaded. If the user clicks once the cross-fade begins, you'd use the new image.
I don't think the complexity of a CATransition is worth it in this case. (Core Animation and layers are a little tricky.)
What I would do is to create a 3-second repeating NSTimer that triggers a cross-fade to the next image for each firing of the timer. I'd use UIView animation to animate the opacity of a view.
The timer would use an instance variable in the view controller to keep track of the current image frame index.
I'd then set the user interaction enabled flag on the image view to YES and attach a tap gesture recognizer. The method for the gesture recognizer would stop the timer, get the index of the current animation frame and use it to load the new URL.
I wrote a sample project on github called Animate-img (link) that does cross-fade animation using a pair of image views stacked on top of each other. It installs the first frame in the bottom view, the second frame in the top view, and makes the top view transparent. It animates the opacity of the top view from 0 to 1.0. Then it switches the bottom image view to image 3, and fades the top view's opacity back to 0, revealing image 3 in the sequence. It then repeats the process, fading the top image view in and out and swapping the image in the currently invisible image view so it reveals a new image with the next opacity change.
You could alternately use the UIView class method +transitionFromView:toView:duration:options:completion:
to do your fade animation, but you'd still have to have a pair of image views and manage swapping them in and out.
Upvotes: 1
Reputation: 1313
I have a few thoughts:
Make the two NSArrays into a single NSDictionary, so that you can keep associated data grouped together and you don't have to worry about index numbers:
NSDictionary * imageToURLMapping = @{ @"urlString1" : image1, @"urlString2" : image 2 ... etc.};
In this manner you can more easily reference and call the URL from the image:
imagesView.image = imageToURLMapping[@"urlString2"];
As far as the transitioning/clicks... I'm thinking you may run into some issues if someone tries to click the image mid-transition (like, will it register as the previous URL, or the transitioning URL?). Maybe like a collection view, or scrollView with pagination may be your best bet for that interface.
But regardless, to know which image was selected, it will depend on how you ultimately implement the images themselves. For example, you could add a target/action method for each image to respond to, example:
NSArray * urlKeys = [imageToURLMapping allKeys];
for(NSString * url in urlKeys){
// iterate over all of the images and add an action
[imageToURLMappaing[url] addTarget:self
action:@selector(goToURL:)
forControlEvent:UIControlEventTouchUpInside];
}
// ---- further down in the code --- //
-(void) gotToURL:(id)sender
{
UIImage * selectedImage = (UIImage *)sender;
NSString * selectedURL = [[imageToURLMapping allKeysForObject:selectedImage] firstObject];
[[UIApplication sharedApplication] openURL:selectedURL];
}
I hope this was at least a little helpful :D
Upvotes: 0