Reputation: 1448
I'm using storyboard. I have a 2 UIViewControler: view1 and view2. When pressing any of 6 button on view1 a segue is performed and therefore this method is called: prepareForSegue:. Now I would like to animate the view1 before it performs the segue with 6 custom images called navExitFrame1, navExitFrame2... and then show a default animation set in the storyboard under Modal>flip horizontal.
EDIT:
I am now using this code:
void (^animationBlock)() = ^{
NSArray *images = @[[UIImage imageNamed:@"navExitFrame1.png"],
[UIImage imageNamed:@"navExitFrame2.png"],
[UIImage imageNamed:@"navExitFrame3.png"],
[UIImage imageNamed:@"navExitFrame4.png"],
[UIImage imageNamed:@"navExitFrame5.png"],
[UIImage imageNamed:@"navExitFrame6.png"]];
UIImage *myimage = [UIImage imageNamed:@"profile.png"];
[profileButton.imageView setImage:myimage];
[self.view bringSubviewToFront:imageView];
imageView.hidden = NO;
NSUInteger imagesCount = [images count];
for(NSUInteger i=0; i<imagesCount; i++) {
[UIView addKeyframeWithRelativeStartTime:i/(CGFloat)imagesCount
relativeDuration:1/(CGFloat)imagesCount
animations:^{
imageView.image = images[i];
}];
}
};
[UIView animateKeyframesWithDuration:1 delay:0 options:UIViewKeyframeAnimationOptionCalculationModeDiscrete animations:animationBlock completion:^(BOOL finished) {
if (sender == feelingsButton) {
NSString *save = @"feelings";
[[NSUserDefaults standardUserDefaults] setObject:save forKey:@"segueID"];
} else if (sender == placesButton) {
NSString *save = @"places";
[[NSUserDefaults standardUserDefaults] setObject:save forKey:@"segueID"];
}else if (sender == peopleButton) {
NSString *save = @"people";
[[NSUserDefaults standardUserDefaults] setObject:save forKey:@"segueID"];
}else if (sender == settingsButton) {
NSString *save = @"settings";
[[NSUserDefaults standardUserDefaults] setObject:save forKey:@"segueID"];
}else if (sender == profileButton) {
NSString *save = @"profile";
[[NSUserDefaults standardUserDefaults] setObject:save forKey:@"segueID"];
}else if (sender == mainWebView || sender == mainWebView.gestureRecognizers) {
NSString *save = @"newsfeed";
[[NSUserDefaults standardUserDefaults] setObject:save forKey:@"segueID"];
}
[self performSegueWithIdentifier:@"ContentVWS" sender:nil];
}];
}
What is happening here is that the animation is taking place but in the space of a MICROsecond, I tried modifying the value of the Duration in
animateKeyframesWithDuration:1
but nothing changes. Also after putting a breakpoint in the for loop I realise that no images are shown except for the last one but when I go in the build phases the images are listed as copy resource bundle and the image names are spelled correctly possibly that is why it is taking place in such a short period of time. Also maybe the values of
UIView animateKeyframesWithDuration:1 delay:0 options:UIViewKeyframeAnimationOptionCalculationModeDiscrete animations:animationBlock completion:^(BOOL finished) {
are incorrect, I NSloged them in the completion but only the variable i is correct and imagesCount is correct too but when I do i/(CGFloat)imagesCount is seems to always be returning 0 for some reason. Does that have anything to do with it?
Upvotes: 3
Views: 1441
Reputation: 668
Ok, it seems like the new keyframe animation method in iOS7 doesn't want to play nicely with changes in uiimage on an image view, so we will have to use a CAKeyframe animation instead: This answer comes in part from here: http://stackoverflow.com/questions/16025769/how-do-i-simultaneously-animate-a-uiimageviews-image-and-the-uiimageview-itself
-(IBAction)animateImagesThenPushView:(id)sender{
NSArray *images = @[[UIImage imageNamed:@"navExitFrame1.png"],
[UIImage imageNamed:@"navExitFrame2.png"],
[UIImage imageNamed:@"navExitFrame3.png"],
[UIImage imageNamed:@"navExitFrame4.png"],
[UIImage imageNamed:@"navExitFrame5.png"],
[UIImage imageNamed:@"navExitFrame6.png"]];
NSMutableArray *keyTimes = [NSMutableArray arrayWithCapacity:images.count];
for (int i = 0; i<images.count; i++) {
keyTimes[i] = @(0.0 + (i+1)*(1.0/images.count));
}
CAKeyframeAnimation *imageAnimation = [CAKeyframeAnimation animationWithKeyPath:@"contents"];
imageAnimation.calculationMode = kCAAnimationDiscrete; // or maybe kCAAnimationPaced
imageAnimation.duration = .5;
imageAnimation.keyTimes = keyTimes;
imageAnimation.repeatCount = 0;
// the following method will need to be implemented to cast your UIImage array to CGImages
imageAnimation.values = [self animationCGImagesArrayFromImageArray:images];
imageAnimation.delegate = self;
[self.imageView.layer addAnimation:imageAnimation forKey:@"content"];
}
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
self.imageView.image = [UIImage imageNamed:@"navExitFrame6.png"];
// put your segue logic here to push the next view
}
-(NSArray*)animationCGImagesArrayFromImageArray:(NSArray*)imageArray {
NSMutableArray *array = [NSMutableArray arrayWithCapacity:imageArray.count];
for (UIImage *image in imageArray) {
[array addObject:(id)[image CGImage]];
}
return [NSArray arrayWithArray:array];
}
Upvotes: 3