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

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";

Related

Partial pagecurl animation with swift

I'm looking for a way to indicate a pagecurl animation on an uiview to give the user a hint that he can scroll through some pages. It should be some kind of partial pagecurl.
The problem is that I don't know how to do that. I found some tutorials but only for objective c and I don't know how transfer it into swift:
[UIView animateWithDuration:1.0
animations:^{
CATransition * animation = [CATransition animation];
[animation setDuration:1.2f];
animation.startProgress = 0.0;
animation.endProgress = 0.6;
[animation setTimingFunction:UIViewAnimationCurveEaseInOut];
[animation setType:#"pageCurl"];
[animation setSubtype:#"fromRight"];
[animation setRemovedOnCompletion:NO];
[animation setFillMode: #"extended"];
[animation setRemovedOnCompletion: NO];
[[self.animatedUIView layer] addAnimation:animation
forKey:#"pageFlipAnimation"];
[self.animatedUIView addSubview:tempUIView];
}
];
http://www.iostute.com/2015/04/how-to-implement-partial-and-full-page.html
UIView.animate(withDuration: 1.0, animations: {
let animation = CATransition()
animation.duration = 1.2
animation.startProgress = 0.0
animation.endProgress = 0.6
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
animation.type = "pageCurl"
animation.subtype = "fromRight"
animation.isRemovedOnCompletion = false
animation.fillMode = "extended"
self.animatedUIView.layer.add(animation, forKey: "pageFlipAnimation")
self.animatedUIView.addSubview(tempUIView)
})
For your help I have uppdatedt the same code to the latest version
UIView.animate(withDuration: 1.0, animations: {
let animation = CATransition()
animation.duration = 1.2
animation.startProgress = 0.0
animation.endProgress = 0.6
animation.type = CATransitionType(rawValue: "pageCurl")
animation.subtype = CATransitionSubtype(rawValue: "fromRight")
animation.isRemovedOnCompletion = false
animation.fillMode = CAMediaTimingFillMode(rawValue: "extended")
animation.isRemovedOnCompletion = false
if let animation = animation as? CATransition{
self.view.layer.add(animation, forKey: "pageFlipAnimation")
self.viewDidLoad()
}
self.view.addSubview(self.TableView)
})
I think you can use UIPageViewController.
I did something like this for my project. This tutorial is helpful.
https://spin.atomicobject.com/2015/12/23/swift-uipageviewcontroller-tutorial/

Animate button two Labels Text change

Here the issue is , when i was tap the button the two labels text will be change,but i'm not able to display that animated function here the my code,
CABasicAnimation *rotate =
[CABasicAnimation animationWithKeyPath:#"transform.rotation"];
rotate.byValue = #(M_PI*1); // Change to - angle for counter clockwise rotation
rotate.duration = 0.4;
[_button.layer addAnimation:rotate
forKey:#"myRotationAnimation"];
CATransition *animation = [CATransition animation];
animation.duration = 1.0;
animation.type = kCATransitionFromBottom;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
[_name1.layer addAnimation:animation forKey:#"changeTextTransition"];
[_name2.layer addAnimation:animation forKey:#"changeTextTransition"];
// Change the text
_from.text = #"new 222text";
_to.text = #"new text";
but i want change like this,
When i tapped that arrow button ,from and to address will be change up and down animation.Can you please help me ,i'm trying but i can not figure out like that,Thank you.
Try this code to animate your label:
- (CAAnimation*)moveup;
{
CABasicAnimation *animation = [CABasicAnimation animation];
animation.keyPath = #"position.y";
animation.fromValue = #-500;
animation.toValue = #10;
animation.duration = 0.25;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
[label1.layer addAnimation:animation forKey:#"basic"];
[label2.layer addAnimation:animation forKey:#"basic"];
label1.layer.position = CGPointMake(0,20);
label2.layer.position = CGPointMake(0,20);
return animation;
}
and add the dimention parameter according to your need.
hope this will work fine.
you can rotate through this code:
-(CAAnimation*)rotate
{
CGRect boundingRect = CGRectMake(350, -500, -5,-5);
CAKeyframeAnimation *orbit = [CAKeyframeAnimation animation];
orbit.keyPath = #"position";
orbit.path = CFAutorelease(CGPathCreateWithEllipseInRect(boundingRect, NULL));
orbit.duration =0.5;
orbit.additive = YES;
orbit.repeatCount = HUGE_VALF;
orbit.calculationMode = kCAAnimationPaced;
orbit.rotationMode = kCAAnimationRotateAuto;
[btnScan.layer addAnimation:orbit forKey:#"orbit"];
return orbit;
}
I found a method for text change for the labels while button action,
bool isShown = false;
In the button Action :
- (IBAction)textChange:(id)sender {
if (!isShown) {
from.frame = CGRectMake(31, 220, 217 , 38);
to.frame = CGRectMake(31, 275, 217 , 38);
[UIView animateWithDuration:0.25 animations:^{
from.frame = CGRectMake(31, 275, 217, 38);
to.frame = CGRectMake(31, 220, 217 , 38);
}];
isShown = true;
} else {
[UIView animateWithDuration:0.25 animations:^{
from.frame = CGRectMake(31, 220, 217, 38);
to.frame = CGRectMake(31, 275, 217, 38);
}];
isShown = false;
}
}
Thank you.

kCAMediaTimingFunctionEaseInEaseOut not affecting UIImageView

I have a cycle of images I am trying to fade from one to the other using kCAMediaTimingFunctionEaseInEaseOut so its not so abrupt. My UIImageView is receiving the objects from a MutableArray. Here is the code I am using to achieve the fade affect.
imageViewContainer = [UIView new];
imageViewContainer.frame = CGRectMake(0, 0, 320, 620);
imageViewContainer.backgroundColor = [UIColor clearColor];
[self.view1 addSubview:imageViewContainer];
for (int i = 0; i < [homescreenPictureArray count]; i++) {
homescreenPictureView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 50, 320, 620)];
homescreenPictureView.animationImages = homescreenPictureArray;
homescreenPictureView.animationDuration = 15;
[homescreenPictureView setAlpha:1.0f];
homescreenPictureView.contentMode = UIViewContentModeScaleAspectFill;
[imageViewContainer.layer addAnimation:pictureDisolve forKey:nil];
[imageViewContainer addSubview:homescreenPictureView];
pictureDisolve = [CATransition animation];
pictureDisolve.duration = 1.0f;
pictureDisolve.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
pictureDisolve.type = kCATransitionFade;
[homescreenPictureView.layer addAnimation:pictureDisolve forKey:#"imageViewContainer"];
[homescreenPictureView startAnimating];
I receive no errors when compiling yet its not affecting the images. Clarification on why its not working would be appreciated. Thanks in advance!
The transition type you're using is wrong. You need to use kCATransitionFade.
You need to specify the key value. for example #"subviews".
it defines, when and what will be transitioned.
pictureDisolve = [CATransition animation];
pictureDisolve.duration = 1.0f;
pictureDisolve.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
pictureDisolve.type = kCATransition;
[homescreenPictureView.layer addAnimation:pictureDisolve forKey:#"subviews"];
So I'm working on a different project now but I figured I would give a good example of the kCATransitionFade for anyone who views this in the future.
`-(void) fadeIn {
view1.image = background1;
view2.image = background2;
CATransition *fadeIn = [CATransition animation];
fadeIn.duration = 2.0f;
fadeIn.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
fadeIn.type = kCATransitionFade;
fadeIn.delegate = self;
[self.view.layer addAnimation:fadeIn forKey:nil];
view1.hidden = YES;
view2.hidden = NO;
NSLog(#"Image 1");
}
-(void) fadeOut {
view1.image = background1;
view2.image = background2;
CATransition *fadeIn = [CATransition animation];
fadeIn.duration = 2.0f;
fadeIn.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
fadeIn.type = kCATransitionFade;
fadeIn.delegate = self;
[self.view.layer addAnimation:fadeIn forKey:nil];
view1.hidden = NO;
view2.hidden = YES;
NSLog(#"Image 2");
}
`
For my project I left it for use as [self fadeIn] or [self fadeOut] but if you would like you can combine them into single function by calling
-(void) fadeFunction {
if (self.view == view1) {
[self fadeIn];
} else {
[self fadeOut];
}
}

How to easily use standard variants timing functions

I am wondering if there is a way to quickly use more different timing functions across an app. For instance using Robert Penner's, many toolkits expose them and I am surprised Apple doesn't.
Basically a way to have a block based command as flexible as animateWithDuration:delay:options:animations:completion: in UIView.
I come up with this solution and it would be great to know if there are better alternatives.
// UIView+CustomTimingFunction.h
#import <UIKit/UIKit.h>
typedef enum {
CustomTimingFunctionDefault,
CustomTimingFunctionLinear,
CustomTimingFunctionEaseIn,
CustomTimingFunctionEaseOut,
....
} CustomTimingFunction;
#interface UIView (CustomTimingFunction)
- (void)animateProperty:(NSString *)property from:(id)from to:(id)to withDuration:(NSTimeInterval)duration customTimingFunction:(CustomTimingFunction)customTimingFunction competion:(void (^)(void))competion;
#end
and
// UIView+CustomTimingFunction.m
#import "UIView+CustomTimingFunction.h"
#implementation UIView (CustomTimingFunction)
- (void)animateProperty:(NSString *)property from:(id)from to:(id)to withDuration:(NSTimeInterval)duration customTimingFunction:(CustomTimingFunction)customTimingFunction competion:(void (^)(void))competion
{
[CATransaction begin]; {
[CATransaction setCompletionBlock:competion];
if([property isEqualToString:#"frame"]){
CGRect fromRect = [from CGRectValue];
CGPoint fromPosition = CGPointMake(CGRectGetMidX(fromRect), CGRectGetMidY(fromRect));
CGRect toRect = [to CGRectValue];
CGPoint toPosition = CGPointMake(CGRectGetMidX(toRect), CGRectGetMidY(toRect));
CABasicAnimation *positionAnimation = [CABasicAnimation animationWithKeyPath:#"position"];
positionAnimation.timingFunction = [[self class] functionWithType:customTimingFunction];
positionAnimation.fromValue = [NSValue valueWithCGPoint:fromPosition];
positionAnimation.toValue = [NSValue valueWithCGPoint:toPosition];
CABasicAnimation *boundsAnimation = [CABasicAnimation animationWithKeyPath:#"bounds"];
boundsAnimation.timingFunction = [[self class] functionWithType:customTimingFunction];
boundsAnimation.fromValue = from;
boundsAnimation.toValue = to;
CAAnimationGroup * group =[CAAnimationGroup animation];
group.removedOnCompletion=NO;
group.fillMode=kCAFillModeForwards;
group.animations = #[positionAnimation,boundsAnimation];
group.duration = duration;
[self.layer addAnimation:group forKey:property];
}else{
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:property];
animation.duration = duration;
animation.timingFunction = [[self class] functionWithType:customTimingFunction];
animation.fillMode = kCAFillModeForwards;
animation.removedOnCompletion = NO;
animation.fromValue = from;
animation.toValue = to;
[self.layer addAnimation:animation forKey:animation.keyPath];
}
} [CATransaction commit];
}
+(CAMediaTimingFunction *)functionWithType:(CustomTimingFunction)type
{
switch (type) {
case CustomTimingFunctionDefault:
return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault];
break;
case CustomTimingFunctionLinear:
return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
break;
case CustomTimingFunctionEaseIn:
return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
break;
case CustomTimingFunctionEaseOut:
return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
break;
case CustomTimingFunctionEaseInOut:
return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
break;
....
}
NSLog(#"Couldn't find CustomTimingFunction, will return linear");
return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
}
#end
Thanks!

how to continuous bouncing uibutton between two points

I'm new to iPhone developing,am using folling code to animate my UIButton it's animating perfectly but when i click the button the action not firing. plese help me out from this.
[UIButton animateWithDuration:3.0
delay:0.0f
options: UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse | UIViewAnimationOptionBeginFromCurrentState
animations: ^(void){
CGPoint p = Mybutton.center;
p.y += 100;
Mybutton.center = p;
}
completion:NULL];
Is this code in the button action or viewDidLoad? Try this one :
- (IBAction)buttonAnimation:(id)sender {
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:#"position"];
animation.duration = .3;
animation.repeatCount = 5;
animation.fromValue = [NSValue valueWithCGPoint:yourButton.center];
animation.toValue = [NSValue valueWithCGPoint:CGPointMake(yourButton.center.x, yourButton.center.y-30)];
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
animation.autoreverses = YES;
animation.removedOnCompletion = NO;
[yourButton.layer addAnimation:animation forKey:#"position"];}
You should put it in the button action.
Hope it helps

Resources