Pause and Resume "Line" growth animation - ios

I have tried so many ways but could not do it smoothly, I am a kind a newB in animations any help would be appreciated.
Code I Tried:
I have the buttons and the labels in need to add in two arrays. eventBtnsPopUpArray and eventLabelsPopUpArray. I try to add them in a loop and the animation is not smooth.
if ([eventBtnsPopUpArray count]>0)
{
CABasicAnimation* scalingAnimation;
scalingAnimation = [CABasicAnimation animationWithKeyPath:#"frame.size"];;
scalingAnimation.fromValue = [NSNumber numberWithFloat:0];
scalingAnimation.toValue = [NSNumber numberWithFloat:1024];
scalingAnimation.duration = 5.0;
scalingAnimation.cumulative = YES;
scalingAnimation.removedOnCompletion = NO;
scalingAnimation.fillMode = kCAFillModeForwards;
[calendarEventView.layer addAnimation:scalingAnimation forKey:#"rotationAnimation"];
for (int k=0; k<[eventBtnsPopUpArray count]; k++)
{
UIButton *btn = [eventBtnsPopUpArray objectAtIndex:0];
UILabel *lbl = [eventLabelsPopUpArray objectAtIndex:0];
[UIView animateWithDuration:2
delay:0
options: UIViewAnimationCurveEaseOut
animations:^{
[self addSubview:btn];
[self addSubview:lbl];
}
completion:^(BOOL finished){
[self pauseLayer:calendarEventView.layer];
[self resumeLayer:calendarEventView.layer];
}
];
}
if (calendarEventView.frame.size.width < 1024) {
[UIView beginAnimations:#"DrawLineTillEnd" context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
calendarEventView.frame = CGRectMake(0, 65, 1024, 7);
[UIView commitAnimations];
}
}
//Pause and resume layer functions
-(void)pauseLayer:(CALayer*)layer
{
CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
layer.speed = 0.0;
layer.timeOffset = pausedTime;
}
-(void)resumeLayer:(CALayer*)layer
{
CFTimeInterval pausedTime = [layer timeOffset];
layer.speed = 1.0;
layer.timeOffset = 0.0;
layer.beginTime = 0.0;
CFTimeInterval timeSincePause =
[layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
layer.beginTime = timeSincePause;
}

I don't think you need to use core-animation, just use an NSTimer and adjust the frame (width) of the UIView using a changing variable... A simple conditional statement (if-statement) checking the width can stop it at a certain point and add the first desired UIButton. When clicked this button will change a BOOLEAN which will trigger the code in the NSTimer to continue line-growth until it reaches the next width defined by the next if-statement. etc.

I dont know how you can do this using coreplot or coreanimation but doing this is really simple by view animation
for example
-(void)animateLine{
UILabel *labelObj = [[UiLabel alloc]init];
//Set background image and height of label say 100 pixel
for(int incrementer = 0; incrementer<100; incrementer ++)
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.01];
[labelObj setFrame:cgRectMake(0,100,incrementer,20)];
[uiview commitAnimation];
}
}

Related

Image Animation. Rotate Image like a coin rotation

I have a situation where I have to rotate the image like a coin. I am doing as follows.
CATransition* transition = [CATransition animation];
transition.startProgress = 0;
transition.endProgress = 1.0;
transition.type = #"flip";
transition.subtype = #"fromRight";
transition.duration = 1.0;
transition.repeatCount = 15;
[rotateimageView.layer addAnimation:transition forKey:#"transition"];
It is rotating the image but it is not completely rotating it Please check the video.
https://www.dropbox.com/s/x4t2aqyscgecqfb/animationVideo.mov?dl=0
It looks like rotating but the right pointing arrow never points left. I want it to point left and right as a complete coin animation.
Check out the following article in which I explained how to rotate a banner. Maybe you can apply the same techniques in your application.
http://highoncoding.com/Articles/876_Creating_a_Flipping_Tweets_View.aspx
-
(void) updateFlippingView:(NSTimer *) timer
{
if(index == ([tweets count] -1))
{
index = 0;
}
UILabel *messageLabel = (UILabel *) [flippingView viewWithTag:MESSAGE_LABEL_TAG];
[UIView animateWithDuration:1.0 animations:^{
[UIView animateWithDuration:2.0 animations:^{
messageLabel.alpha = 0.0;
} completion:^(BOOL finished) {
[UIView animateWithDuration:1.0 animations:^{
messageLabel.alpha = 1.0;
messageLabel.text = [tweets objectAtIndex:index];
}];
}];
flippingView.layer.transform = CATransform3DMakeRotation(rotationIndex *M_PI, 1.0, 0.0, 0.0);
for(UIView *subView in flippingView.subviews)
{
subView.layer.transform = CATransform3DMakeRotation(rotationIndex *M_PI, 1.0, 0.0, 0.0);
}
}
completion:^(BOOL finished) {
rotationIndex = rotationIndex == 1 ? 2 :1;
}];
index++;
}

Stop animateWithDuration

I have a cycle animate in viewController
- (void)moveAnimating
{
[UIView animateWithDuration:2.0f animations:^{
_backgroundView.center = CGPointMake(self.center.x , self.center.y - kMoveDistanceHeight);
} completion:^(BOOL finished) {
if (_backgroundView.animating)
{
[_backgroundView moveAnimating];
}
}];
}
I want stop this animate When the viewController viewWillDisappear:
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
_backgroundView.animating = NO;
[_backgroundView.layer removeAllAnimations];
}
Because the animation is conflict with dismissViewcontrollerAnimation.
Question:
[_backgroundView.layer removeAllAnimations];
not work...
How to stop the animation?
Help me,thanks.
You are canceling animations correctly:
[_backgroundView.layer removeAllAnimations];
But you might forget about importing QuartzCore.h:
#import <QuartzCore/QuartzCore.h>
If it doesn't help try this:
[CATransaction begin];
[_backgroundView.layer removeAllAnimations];
[CATransaction commit];
If it doesn't help try to add this line to the code above:
[CATransaction flush];
Te solution from #KlimczakM didn't work for me.
I'm running an 'animateWithDuration' block that moves and image, and I use the next code to pause and resume the animation:
-(void)pauseLayer:(CALayer*)layer {
CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
layer.speed = 0.0;
layer.timeOffset = pausedTime;
}
-(void)resumeLayer:(CALayer*)layer {
CFTimeInterval pausedTime = [layer timeOffset];
layer.speed = 1.0;
layer.timeOffset = 0.0;
layer.beginTime = 0.0;
CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
layer.beginTime = timeSincePause;
}
This is from the Apple Documentation at this link.

"Glitch" during UIView Intro CAAnimation

I'm trying to add an Animation to a UIView. The objective of the animation is to "animate" the View appearing on screen (instead of just appearing there).
The animation is all size scaling: start from 5%, go up to 120% and then very quickly back to 100% of the regular scale.
My issue is that the full scale UIView appears very quickly, before the animation starts.
Here's the code:
UIView * myView = [[UIView alloc] initWithFrame:someFrame];
[self.view addSubview:myView];
[self initialAnimationFor:myView];
-(void) initialAnimationFor:(UIView*)pView {
const CFTimeInterval firstDuration = 0.75f;
const CFTimeInterval secondDuration = 0.025f;
const float initialValue = 0.05f;
const float middleValue = 1.20f;
CABasicAnimation * firstAnimation = [CABasicAnimation animationWithKeyPath:#"transform.scale"];
firstAnimation.duration = firstDuration;
firstAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
firstAnimation.fromValue = [NSNumber numberWithFloat:initialValue];
firstAnimation.toValue = [NSNumber numberWithFloat:middleValue];
CABasicAnimation * secondAnimation = [CABasicAnimation animationWithKeyPath:#"transform.scale"];
secondAnimation.duration = secondDuration;
secondAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
secondAnimation.fromValue = [NSNumber numberWithFloat:middleValue];
secondAnimation.toValue = [NSNumber numberWithFloat:1.0f];
CAAnimationGroup *animationGroup = [CAAnimationGroup new];
animationGroup.duration = firstDuration + secondDuration;
animationGroup.animations = #[firstAnimation, secondAnimation];
[pView.layer addAnimation:animationGroup forKey:nil];
}
Any ideas? Thanks!
I would do a different technique and use chained UIView block animations, like this:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(40, 40, 200, 200)];
myView.backgroundColor = [UIColor redColor];
[self initialAnimationFor:myView];
}
- (void)initialAnimationFor:(UIView*)pView {
pView.transform = CGAffineTransformMakeScale(0.05f, 0.05f);
if (pView.superview == nil) {
[self.view addSubview:pView];
}
[UIView
animateWithDuration:0.75f
animations:^{
pView.transform = CGAffineTransformMakeScale(1.20f, 1.20f);
}
completion:^(BOOL finished) {
[UIView
animateWithDuration:0.25f // <-- Your old value of 0.025f makes the animation VERY quick
animations:^{
pView.transform = CGAffineTransformIdentity;
}
];
}
];
}
With this setup, you get the "grow to slightly larger than 100% and then 'settle' to 100%" effect.
Is this a workable solution?

CABasicAnimation back to its original position after it finish it's 1 cycle

Don't refer CABasicAnimation returns to the original position before the next animation and Objective-C - CABasicAnimation applying changes after animation? and CABasicAnimation rotate returns to original position
i have tried.
below code does,bottom->top->goes left->back to it’s original position.
bottom->top->goes left->back to its original position.
I need bottom->top->goes left.bottom->top->goes left so on…
-(void)addUpDownAnimationForButton:(UILabel*)label
{
CABasicAnimation * bottomAnimation ;
bottomAnimation =[CABasicAnimation animationWithKeyPath:#"transform.translation.y"];
[bottomAnimation setValue:#"animation1" forKey:#"id"];
bottomAnimation.delegate = self;
[UIView setAnimationDidStopSelector:#selector(animationDidStop:finished:)];
bottomAnimation.duration = 2.0;
bottomAnimation.fromValue = [NSNumber numberWithFloat:13];
bottomAnimation.toValue = [NSNumber numberWithFloat:-7];
bottomAnimation.repeatCount = 0;
bottomAnimation.fillMode = kCAFillModeForwards;
bottomAnimation.removedOnCompletion = NO;
[btnSpecialForListing.titleLabel.layer addAnimation:bottomAnimation forKey:#"transform.translation.y"];
}
- (void)animationDidStop:(CAAnimation *)theAnimation2 finished:(BOOL)flag
{
if([[theAnimation2 valueForKey:#"id"] isEqual:#"animation1"]) {
CABasicAnimation *moveAnimation;
moveAnimation=[CABasicAnimation animationWithKeyPath:#"transform.translation.x"];
moveAnimation.duration=3.5;
moveAnimation.repeatCount=0;
moveAnimation.autoreverses=NO;
moveAnimation.fromValue=[NSNumber numberWithFloat:0];
moveAnimation.toValue=[NSNumber numberWithFloat:-400];
moveAnimation.removedOnCompletion = NO;
moveAnimation.fillMode = kCAFillModeRemoved;
[btnSpecialForListing.titleLabel.layer addAnimation:moveAnimation forKey:#"transform.translation.x"];
}
}
Any help would be greatly appreciated.
Thanks !!
Have you tried this?
moveAnimation.fillMode = kCAFillModeForwards;
moveAnimation.removedOnCompletion = NO;
EDIT
As far as I can see you can also use animateWithDuration which has a completion block.
Example would be:
CGRect rect = btnSpecialForListing.titleLabel.frame;
[UIView animateWithDuration:2.0 animations:^{
rect.origin.y = -7;
btnSpecialForListing.titleLabel.frame = rect;
} completion:^(BOOL finished){
[UIView animateWithDuration:3.5 animation:^{
rect.origin.x = -400;
btnSpecialForListing.titleLabel.frame = rect;
}];
}];
Swift 4.2/5:
moveAnimation.fillMode = .forwards
moveAnimation.isRemovedOnCompletion = false

iOS animation with duration and autoreverse

I am animating an UIImageView with the UIView block API. My animation fades the UIImageView In and Out continuously. How can I animate this only for a specific time duration ?
I have put up this piece of code
float tempDuration = 5.0;
[UIView animateWithDuration:tempDuration
delay:0
options:UIViewAnimationOptionAutoreverse | UIViewAnimationOptionAllowUserInteraction
animations:^{
_imageView.alpha = 1;
}
completion:nil];
First of all allow me to introduce an article that is awesome to understand some features of the animations:
Controlling Animation Timming
In this article you have a part that shows what you want.
You want something like this:
Therefore you can configure that in the following way:
-(void) animateImageView:(UIImageView*) imageView
withDuration:(int) duration
withRepeatCount: (int) repeatCount {
CABasicAnimation *opacityAnim = [CABasicAnimation animationWithKeyPath:#"opacity"];
opacityAnim.fromValue = #1.0;
opacityAnim.toValue = #0.0;
opacityAnim.autoreverses = YES;
opacityAnim.duration = duration/2.0/repeatCount;
opacityAnim.removedOnCompletion = YES;
opacityAnim.repeatCount = repeatCount;
[imageView.layer addAnimation:opacityAnim forKey:nil];
}
This way you guarantee that your animation will always be 5 seconds and you can tune in the number of repetitions.
Maybe you could try CABasicAnimation instead if [UIView animateWithDiration: ... ]
it should be something like this:
CABasicAnimation *opacityAnim = [CABasicAnimation animationWithKeyPath:#"opacity"];
opacityAnim.fromValue = [NSNumber numberWithFloat:1.0];
opacityAnim.toValue = [NSNumber numberWithFloat:0.0];
opacityAnim.autoreverses = YES;
opacityAnim.duration = duration;
opacityAnim.removedOnCompletion = YES;
opacityAnim.repeatCount = 5;
[imageView.layer addAnimation:opacityAnim forKey:nil];
You can do the following changes to do your work.
- (void)animateImageView{
static int animcount = 1;
float tempDuration = 1.0;
[UIView animateWithDuration:tempDuration
delay:0
options: UIViewAnimationOptionAutoreverse
animations:^{
self.imgView.alpha = 1;
}
completion:^(BOOL finished) {
if(finished && animcount<5){
animcount+=1;
[self animateImageView];
}
else if (finished && animcount==5){
[self.imgView.layer removeAllAnimations];
}
}];
}

Resources