Swapping a UIImageView's image while rotating and moving leaves traces of original image - iphone

I am taking the "Flipped Text" imageView and rotating it while moving it downwards on the screen and adjusting the frame. I am also swapping out the image for a different, but similar image.
Everything works as indicated except for the image crossfade is still showing the original position for the fade-out instead of following the movement. This screenshot shows the original, transition and end states for the animation, and clearly shows the problem.
My code looks like this (logoImage is a UIImageView):
// Swap it
self.logoImage.image = [UIImage imageNamed:#"logo.png"];
CATransition *transition = [CATransition animation];
transition.duration = duration;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionFade;
[self.logoImage.layer addAnimation:transition forKey:nil];
// Spin it
CABasicAnimation* spinAnimation = [CABasicAnimation animationWithKeyPath:#"transform.rotation"];
spinAnimation.toValue = [NSNumber numberWithFloat:6*M_PI];
spinAnimation.duration = duration;
spinAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
spinAnimation.removedOnCompletion = YES;
spinAnimation.fillMode = kCAFillModeForwards;
[self.logoImage.layer addAnimation:spinAnimation forKey:#"spinAnimation"];
// Shrink it and Move it
CGRect newFrame = [self logoFrameForInterfaceOrientation:self.interfaceOrientation];
[UIView animateWithDuration:duration
delay:0.0
options:UIViewAnimationCurveEaseOut
animations:^{
self.logoImage.frame = newFrame;
}
completion:nil];
How can I make the crossfade of the image swap happen in place?

Try swapping the image in the completion block. (currently nil)
edit:
If they are substantially different, you can use a second UIImageView. Fade one out while you fade one in. You can either do this while they are translating, or wait for the "shrunken" original to arrive and fade it out while the "better" smaller version fades in.
Then remove the unneeded extra view in the completion block of that animation.

Related

Slide Image 400px from Current Location with CATransition

I have a UIImageView that I have aligned right where I want it in my XIB file. When my viewController is called, I would like to have the image move to the right about 400px over the course of 3 seconds. Then I would like the image to fade-out.
I have been playing around with QuartzCore and CATransition and have been able to fade an image out over time with:
CATransition *animation = [CATransition animation];
animation.type = kCATransitionFade;
animation.duration = 0.4;
[coverImage.layer addAnimation:animation forKey:nil];
coverImage.hidden = true;
However, I would like the image to slide to the right. Anyone know how to do this? Thank you!
Using CATransition for moving images is quite overkill. I would recommend using UIView animations, then you would simply do
// UIImageView *coverImage = ...
// This will move the image to the right and then fade it out.
[UIView animateWithDuration:3 animations:^{
coverImage.center = CGPointMake(coverImage.center.x + 400, coverImage.center.y);
coverImage.alpha = 0.0f;
}];
UIImageView *coverImage=[[UIImageView alloc] initWithFrame:CGRectMake(0, 300, 200, 400)];
coverImage.backgroundColor = [UIColor blackColor];
[self.view addSubview:coverImage];
[UIView animateWithDuration:0.4 animations:^{
coverImage.frame = CGRectInset(coverImage.frame, -400, 0);
coverImage.alpha = 0.0f;
}];
//there is subtype property which provides transition from right or from left. You have to just set this property as given below
animation.subtype = kCATransitionFromRight;

Multiple CAAnimations On Different Views Simultaneously

I'm trying execute a couple of animations at the same time. One is transitioning from one uimageview to another and the other is animating translation.x of a label. The label resides on top of uiimageview.
But what I get is either translation working fine and transition happens immediately, or the transitioning -based on hidden property - also applies to my label which should only be shifted (it also goes from hidden to visible). I can't use caanimationgroup because they apply to different views.
//CAKeyFrameAnimation for sliding the label
...
CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:#"transform.translation.x"];
NSArray *xValues = #[[NSNumber numberWithFloat:myLabel.bounds.origin.x],
[NSNumber numberWithFloat:myLabel.bounds.origin.x + screenHalf],
[NSNumber numberWithFloat:myLabel.bounds.origin.x + screenHalf * 4]];
[anim setValues:xValues];
NSMutableArray *timeFrames = [NSMutableArray array];
CGFloat timeStep = 1.0 / ([xValues count] - 1);
for (NSInteger i = 0; i < [xValues count]; i++)
{
[timeFrames addObject:[NSNumber numberWithFloat:timeStep * i]];
}
[anim setKeyTimes:timeFrames];
[anim setDuration:duration];
[anim setFillMode:kCAFillModeForwards];
[anim setRemovedOnCompletion:FALSE];
[myLabel.layer addAnimation:anim forKey:nil];
...
//Transitioning from uiimageview to another one
...
CATransition *transition = [CATransition animation];
[transition setDuration:duration];
[transition setType:kCATransitionFade];
//These two are uiimageviews i'm switching from and to
initial.hidden = TRUE;
next.hidden = FALSE;
//Initial and next are subviews of container which itself is a subview of viewcontroller's main view
[container.layer addAnimation:transition forKey:#""];
If I call the animations like above the transition occurs immediately and label slides across screen correctly. If I change the last line to:
[self.view.layer addAnimation:transition forKey:#""];
Then hidden animation also applies to myLabel. What is the fix for combining animations like above, and also more elaborately what is the cause?
I would wrap the entire code in a CATransaction to group the different CAAnimations into a single group.
Psuedo-code for using this with CAKeyFrameAnimation would look like:
[CATransaction begin];
// set completion block if you want
[CATransaction setCompletionBlock:^{ NSLog(#"I'm done"); }];
// start a keyframe animation
CAKeyframeAnimation *key1 = .....
// start another keyframe animation block
CAKeyframeAnimation *key2 = ......
// Maybe do a basic animation
CABasicAnimation *anim1 = .....
// close out all the animations and have them start
[CATransaction commit];

iPhone: changing CATransition causes UIActivityIndicatorView to stop animating

I have implemented a non-default animation for when a new view is pushed onto the screen (see code below). For some reason once I implemented this code it caused my UIActivityIndicatorViews to stop working. They will been shown on the screen but not animate even when their isAnimating is true. I figure it is because of me changing the CATransition, but can't figure out how to fix it for the UIActivityIndicatorView.
change default animation for push
CATransition* fade = [CATransition animation];
fade.duration = 1.0;
fade.type = kCATransitionFade;
fade.subtype = kCATransitionFromTop;
[self.navigationController.view.layer
addAnimation:fade forKey:kCATransition];
later on in viewDidLoad I start the animation
[spinner startAnimating];
but the spinner will show and not animate. For some reason the very first spinner I have animates but after that nothing.
I was encountering this problem when using a CATransition inside a subclass of UINavigationController to have a custom animation when pushing or popping view controllers.
Inside a method of this UINavigationController's subclass I had this code:
- (void)addCustomTransition
{
CATransition* transition = [CATransition animation];
transition.duration = kAnimationDuration;
transition.timingFunction =
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionFade;
[self.view.layer addAnimation:transition forKey:nil];
}
However, I later found out you also have to add the same animation to the pushed/popped viewController's view's layer:
- (void)addCustomTransitionToViewController:(UIViewController *)viewController
{
CATransition* transition = [CATransition animation];
transition.duration = kAnimationDuration;
transition.timingFunction =
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionFade;
[self.view.layer addAnimation:transition forKey:nil];
[viewController.view.layer addAnimation:transition forKey:nil]; // this is what was missing
}
This pushed/popped view controller's view is that one that had an UIActivityIndicatorView that wasn't animating properly.
Hope this helps!
just change your time duration from 1.0 to 0.3 or less
just i am tested and it's working

crossfade animation between two UIImages in objective-c doesn't fade out the first UIImage

I want to crossfade between two different UIImages but for a reason i cannot figure out my first UIImage stays when the second one fades in.
Here is the sourcecode of my animation (it does a lot more than just crossfading, but the crossfading is my only problem right now).
I need all of the three animations listed below to be executed at the same time.
CGMutablePathRef thePath = CGPathCreateMutable();
CGPathMoveToPoint(thePath,NULL,startPoint.x, startPoint.y);
CGPathAddLineToPoint(thePath, NULL, endPoint.x, endPoint.y);
CAKeyframeAnimation *positionAnimation =[CAKeyframeAnimation animationWithKeyPath:#"position"];
positionAnimation.path=thePath;
positionAnimation.duration=ti_duration;
positionAnimation.repeatCount=0;
positionAnimation.delegate = self;
positionAnimation.autoreverses=NO;
positionAnimation.fillMode=kCAFillModeForwards;
positionAnimation.removedOnCompletion = NO;
[self.layer addAnimation:positionAnimation forKey:s_direction];
CABasicAnimation *crossFade = [CABasicAnimation animationWithKeyPath:#"contents"];
crossFade.duration = ti_duration;
crossFade.fromValue = (id)img_startImage.CGImage;
crossFade.toValue = (id)img_transferImage.CGImage;
[self.iv_image.layer addAnimation:crossFade forKey:#"animateContentsToTransferState"];
[self.iv_image setImage:img_transferImage];
CAAnimationGroup *theGroup = [CAAnimationGroup animation];
theGroup.duration = ti_duration;
theGroup.repeatCount = 0;
theGroup.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
theGroup.animations = [NSArray arrayWithObjects:/*positionAnimation,*/ crossFade, nil]; // you can add more
[self.layer addAnimation:theGroup forKey:#"move"];
[UIView beginAnimations:#"changeSize" context:nil];
[UIView setAnimationDuration:duration];
self.bounds = CGRectMake(self.bounds.origin.x, self.bounds.origin.y, self.transferSize.width, self.transferSize.height);
[UIView commitAnimations];
The animation method containing this sourcecode is in a subclass of UIView. This subclass contains several UIImages and one UIImageView where the image to be displayed is contained in.
Have i forgotten some essential thing or why is my first image not fading away?
Can it be because it is animated from some other animation at the same time?
I hope someone can help me with this.
Greets
Maverick
Think of CAAnimations as operations applied to the CALayer. The animations current state do not change the layers original contents.
When the original state seems to snap back at the end of the animation it is actually just the animations operation being removed, and the real layers state is being revealed again.
What you need to do is to register a delegate for your animation, and change the actual self.layer.contents when the animation ends.
First:
crossFade.delegate = self;
Then implement:
- (void)animationDidStop:(CABasicAnimation *)animation finished:(BOOL)flag {
self.layer.contents = animation.toValue;
}
Try this code...It worked for me.
-(void)crossFadeImage{
CABasicAnimation *crossFade = [CABasicAnimation animationWithKeyPath:#"contents"];
crossFade.duration = 2.0;
crossFade.fromValue = img1.CGImage;
crossFade.toValue = img2.CGImage;
[self.background.layer addAnimation:crossFade forKey:#"animateContents"];
self.background.image = img2;
}

when cell gets selected in table view i should able to animate the cell before going to another view

CATransition *animation = [CATransition animation];
animation.type = #"suckEffect";
animation.duration = 1.0f;
animation.delegate = self;
animation.timingFunction = UIViewAnimationCurveEaseInOut;
[[tableView cellForRowAtIndexPath:indexPath].layer addAnimation:animation forKey:#"transitionViewAnimation"];
Can any body tell me what are the other types of animations to animate the table cell.
I am selected one of these to animate rows ,tat solved my problem....
pageCurl,
pageUnCurl,
suckEffect,
spewEffect,
cameraIris (from the Photos application),
cameraIrisHollowOpen,
cameraIrisHollowClose,
genieEffect (typically used for deleting garbage),
unGenieEffect,
rippleEffect,
twist,
tubey,
swirl,
charminUltra,
zoomyIn,
zoomyOut,
oglFlip.