Glitch when sliding in UIView with kCATransitionMoveIn - ios

I have a UINavigationController whose UIView slides in from the bottom of the screen when the user presses a button.
Immediately after I set the view's "hidden" property to NO, though, the UINavigationController's view sometimes appears fully in place for one frame, as if the animation was finished already.
This is the code that shows/hides the view:
- (void)showGUI: (bool)show
{
CATransition *transition = [CATransition animation];
transition.duration = 0.5;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
if (!show)
{
transition.type = kCATransitionReveal;
transition.subtype = kCATransitionFromBottom;
}
else
{
transition.type = kCATransitionMoveIn;
transition.subtype = kCATransitionFromTop;
}
[navController.view.superview.layer addAnimation:transition forKey:nil];
navController.view.hidden = !show;
}

CATransition animations are applied when layers are added/removed from the layer you add the animation to. If toggling the hidden property doesn't work, then try removing the view instead.

Related

Transition animation does not take place for every text change

I have added transition animation to UILabel for text change.
But it takes place only once when I add it to layer.
- (IBAction)changeText:(id)sender {
if (!self.transitionAnimation) {
CATransition *animation = [CATransition animation];
animation.duration = 0.5;
animation.type = kCATransitionFade;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation.removedOnCompletion = NO;
[self.label.layer addAnimation:animation forKey:nil];
self.transitionAnimation = animation;
}
self.label.text = [NSString stringWithFormat:#"Text %d",arc4random()];
}
Why do you need to have a strong reference to the animation? That reference doesn't get nil'ed out, and hence your control doesn't enter the if block more than once.
Either nil out the transitionAnimation property on didStop, or don't store a reference at all.
Edit: Also, I don't think you need to have removedOnCompletion as NO.

How to get UILabel to fade text in & out with CATransition?

I'm trying to get a AM/PM lane to fade in & out, but I can't seem to get it to work both ways.
If I only use one it works, but when I try to add two, it just flips back and forth without the proper fade animation.
Can anyone give me some insight on why, and how to fix this?
Heres my code below.
- (void)setState:(MonringNightLabelState)state animated:(BOOL)animated {
CATransition *animationAM = [CATransition animation];
animationAM.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animationAM.type = kCATransitionFade;
animationAM.duration = 0.3;
CATransition *animationPM = [CATransition animation];
animationPM.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animationPM.type = kCATransitionFade;
animationPM.duration = 0.3;
if (animated)
{
[UIView animateWithDuration:0.3
delay:0.0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
[self setState:state animated:NO];
}
completion:^(BOOL finished) {
}];
}
switch (state)
{
case MorningNightLabelStateAM:
{
[self.morningNightLabel.layer addAnimation:animationAM forKey:#"kCATransitionFade"];
self.morningNightLabel.text = #"AM";
}
break;
case MorningNightLabelStatePM:
{
[self.morningNightLabel.layer addAnimation:animationPM forKey:#"kCATransitionFade"];
self.morningNightLabel.text = #"PM";
}
break;
}
}
This is the way I fixed it in swift:
var transitionAnimation = CATransition()
transitionAnimation.type = kCATransitionFade
transitionAnimation.duration = 0.2
transitionAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
transitionAnimation.fillMode = kCAFillModeBoth
self.titleLabel.layer.addAnimation(transitionAnimation, forKey: "fadeAnimation")
self.titleLabel.text = newTitle
which is working for me.
Probably this should be enough:
CATransition *animationPM = [CATransition animation];
animationPM.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animationPM.type = kCATransitionFade;
animationPM.duration = 0.3;
[self.morningNightLabel.layer addAnimation:animationAM forKey:#"kCATransitionFade"];
self.morningNightLabel.text = (state == MorningNightLabelStateAM) ? #"AM" : #"PM";

iphone - undo or reverse kCATransitionPush to send image off screen

I am currently sliding in an animated image from the right of the screen using CATransition:
CATransition *transition = [CATransition animation];
transition.duration = TRANSITION_DURATION;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromRight;
[self.layer addAnimation:transition forKey:nil];
self.image = [UIImage animatedImageNamed:prefix duration:ANIMATION_DURATION];
My question is, how do I slide the image out? Once the image animation cycles through, I want to send it off the screen in the direction from whence it came, i.e. TransitionToRight, but there doesn't seem to be such a transition type. Please suggest how I might accomplish this reverse transition.
Here is how I might write it, if such a reverse transition existed:
[self performSelector:#selector(removeAnimatedImage) withObject:nil afterDelay:ANIMATION_DURATION];
and inside removeAnimatedImage, I would create another CATransition animation with this reverse direction to send it off the screen.
Did you try the kCATransitionFromLeft version of the push transition? It should be the inverse of FromRight.
Not the ideal solution, but one hack is to either animate a change in frame bounds, or applying a translation transform animation:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:TRANSITION_DURATION];
if (enteredFromRight) {
self.transform = CGAffineTransformMakeTranslation(SCREEN_SPACE_WIDTH, 0);
} else {
self.transform = CGAffineTransformMakeTranslation(-SCREEN_SPACE_WIDTH, 0);
}
[UIView commitAnimations];

Implicit animation on CALayer "contents" property

According to the core animation documentation, setting the layer contents should trigger an implicit 0.25 animation that will transition between the new and old images.
I also see many places where people are asking how to remove this implicit animation but for some reason when I try this on my project, I get an instant swap of images.
Reading some more into the documention I saw this code snipped:
- (id<CAAction>)actionForLayer:(CALayer *)theLayer
forKey:(NSString *)theKey {
CATransition *theAnimation=nil;
if ([theKey isEqualToString:#"contents"]) {
theAnimation = [[CATransition alloc] init];
theAnimation.duration = 1.0;
theAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
theAnimation.type = kCATransitionPush;
theAnimation.subtype = kCATransitionFromRight;
}
return theAnimation;
}
Which implies that "contents" is not implicitly animated.
I would be very interested to understand this better.
OK, I'm copying some code from an app of mine. First I usually get CATransition not with alloc..init.. but using +animation. Second I'm not seeing that you are adding the transition to a layer. Third I'm not sure that CATransition are implicitly animated, CALayer properties yes.
CATransition *transition = [CATransition animation];
transition.duration = 1;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush;
transition.subtype = slideCATransitionCompareTable[ arc4random() % 4]; //to get a random subtype
[self.slideShowReceiptImageView.layer addAnimation:transition forKey:nil];

fade View IN and OUT

Good Morning everyone,
I'm totally confused with this problem.
I have 3 UIWebViews and what should hapen is webView1 fades in (that works) fades out und WebView2 fades in......
I made it so far with:
CATransition *Animation = [CATransition animation];
[Animation setDuration:4.0];
[Animation setType:kCATransitionFade];
[Animation setSubtype:kCATransitionFade];
[Animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
transitioning = YES;
if (transitioning) {
[self.webView1.layer addAnimation:Animation forKey:nil];
self.webView1.hidden = YES;
self.webView2.hidden = NO;
can anyone help me with that?
And when it fades in the webView fades from white even the background color is set to an other color!
can't I effect the color?
You should use UIView implicit animations. For instance, a cross fade from webView1 to webView2:
[UIView beginAnimations:#"fade" context:nil];
self.webView1.alpha = 0.0;
self.webView2.alpha = 1.0;
[UIView commitAnimations];
If you wanna execute some code after the animation finished, insert this between begin and commit:
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(fadeAnimationDidStop:finished:context:)];
and create the didStop method with the signature
- (void)fadeAnimationDidStop:(NSString*)animationID finished:(NSNumber*)finished context:(void*)context`
transition.type =kCATransitionMoveIn;
transition.subtype =kCATransitionFade;

Resources