Animation with UIViewAnimationOptionRepeat does not repeat - ios

[UIView animateWithDuration:speedOfCutout
delay:0.2f
options:UIViewAnimationCurveEaseInOut | UIViewAnimationOptionRepeat //| UIViewAnimationOptionAutoreverse
animations:^{
CABasicAnimation *animation = [CABasicAnimation animation];
animation.keyPath = #"position.y";
animation.fromValue = #77;
animation.toValue = #600;
animation.duration = speedOfCutout;
[cutout.layer addAnimation:animation forKey: #"basic"];
cutout.layer.position = CGPointMake(160, 61);
[cutout.layer addAnimation:animation forKey: #"basic"];
cutout.layer.position = CGPointMake(160, 61);
[cutout.layer addAnimation:animation forKey: #"basic"];
cutout.layer.position = CGPointMake(160, 61);
}
completion:^(BOOL fin) {
}];
if (CGRectIntersectsRect(cutout.frame, shape.frame)) {
cutout.hidden = YES;
shape.hidden = YES;
[cutoutMovementTimer invalidate];
[self gameOver];
}
I have this code that is supposed to loop the animation until it runs into another shape. But, it only runs through once and does not do anything afterwords.

You're using CoreAnimation object, will not affected by UIView Animation block, remove UIView Animation block and add:
animation.autoreverses = YES;
animation.repeatCount = HUGE_VAL;
It'll work.

Try this:
set animation.repeatCount = -1;
And is the completion block handle the shape change event and stop the animation.

Related

Animating UIview from top to bottom and vice versa

I have a UIView at X=0 and Y=0 location with the height of 110 and UIButton at the bottom of the screen with the height of 50, i want to show both by animating but the UIView must animate from top to to its height and UIButton from bottom to its height, i am totally new with this please help me how to do it.
Following code worked for me to show a search view on top.
if (!isSearchActive) {
[UIView animateWithDuration:0.4
delay:0.1
options: UIViewAnimationOptionCurveEaseIn
animations:^{
searchView.frame = CGRectMake(0, 56, mainWidth, 50);
}
completion:^(BOOL finished){
}];
isSearchActive=YES;
}
else{
[UIView animateWithDuration:0.3
delay:0.1
options: UIViewAnimationOptionCurveEaseIn
animations:^{
searchView.frame = CGRectMake(0, 56, mainWidth, 0);
}
completion:^(BOOL finished){
}];
isSearchActive=NO;
}
Call this code on click of any button to show and hide the view.
Try this for top to bottom Animation:
- (CAAnimation*)movedown;
{
CABasicAnimation *animation = [CABasicAnimation animation];
animation.keyPath = #"position.y";
animation.fromValue = #600;
animation.toValue = #50;
animation.duration = 0.25;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
[trashView.layer addAnimation:animation forKey:#"basic"];
trashView.layer.position =CGPointMake(0,-20);
return animation;
}
and Code for Bottom to Top:
- (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];
[trashView.layer addAnimation:animation forKey:#"basic"];
trashView.layer.position =CGPointMake(0,20);
return animation;
}
for first block of code you can use to animate view but you have to replace your viewcontroller at trashview in code.
and second block use for button but you have to replace your button at trashview.
but you can set value of animation according to your need.
basic animation which may fit your requirement
[UIView transitionWithView:view
duration:0.5
options:UIViewAnimationOptionTransitionNone
animations:^{
//update your frame here;
}
completion:nil];
Please go thru Apple Documentation and stack overflow
private func startAnimation() {
let animation = CABasicAnimation(keyPath: "position.y")
animation.fromValue = 10 //Top Y
animation.toValue = 204 //Bottom Y
animation.duration = 15 * 0.10 //duration * speed
animation.repeatCount = 100
animation.autoreverses = false
animation.isRemovedOnCompletion = true
animation.fillMode = .forwards
self.yourView.layer.add(animation, forKey: "position.y")
}
private func stopAnimation() {
self.yourView.layer.removeAllAnimations()
}

Add a bounce effect to a flip animation

I animated a flip for a pie chart I have. Here is my code"
CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:#"transform.scale.x"];
scaleAnimation.fromValue = [NSNumber numberWithFloat:1.0];
scaleAnimation.toValue = [NSNumber numberWithFloat:0.5];
scaleAnimation.duration = 1.0f;
scaleAnimation.removedOnCompletion = NO;
[self.pieChart addAnimation:scaleAnimation forKey:#"scale"];
animationDidStop:finished:
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:#"transform.scale.x"];
animation.fromValue = [NSNumber numberWithFloat:0.5];
animation.toValue = [NSNumber numberWithFloat:1.0];
animation.duration = 1.0f;
[self.pieChart addAnimation:animation forKey:#"scale"];
How can I add a bounce effect to the second animation? (The animation in animationDidStop:finished:)
Go with a CAKeyFrameAnimation instead of two CABasicAnimation:
CAKeyframeAnimation *scaleAnimation = [CAKeyframeAnimation animationWithKeyPath:#"transform.scale.x"];
scaleAnimation.keyTimes = #[#(0), #(0.5), #(0.9), #(1)];
scaleAnimation.values = #[#(1.0), #(0.5), #(1.1), #(1.0)];
scaleAnimation.duration = 1.0f;
scaleAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
With keyTimes and values, you can specify multiple stances in your animation. Here, I made it start with a scale of 1, animating to a scale of 0.5 (your first animation values), then 1.1 (an overshoot to create a "bounce") and finally 1 (your second animation values). Tweak those to your liking!
If you want to do this animation in two parts, you can keep your first animation, then start a CAKeyFrameAnimation in the animationDidStop:finished: similar to this instead:
CAKeyframeAnimation *scaleAnimation = [CAKeyframeAnimation animationWithKeyPath:#"transform.scale.x"];
scaleAnimation.keyTimes = #[#(0), #(0.8), #(1)];
scaleAnimation.values = #[#(0.5), #(1.1), #(1.0)];
scaleAnimation.duration = 1.0f;
scaleAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
If you instead want to use UIView animation blocks, you'll need to do something similar to this:
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
self.squareView.transform = CGAffineTransformMakeScale(0.5, 1);
} completion:^(BOOL finished) {
[UIView animateWithDuration:1 delay:0 usingSpringWithDamping:0.6 initialSpringVelocity:0 options:0 animations:^{
self.squareView.transform = CGAffineTransformIdentity;
} completion:nil];
}];
You will probably want to play with the params to tweak the animation.

Converting code from CABasicAnimation

I have a animation code that is written using CABasicAnimation just as following:
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:#"position"];
[anim setDelegate:self];
anim.fromValue = [NSValue valueWithCGPoint:img.center];
if (newValue == 0) {
imgCentre.y = centerStart.y - 11 * kCounterDigitDiff;
anim.toValue = [NSValue valueWithCGPoint:imgCentre];
} else
anim.toValue = [NSValue valueWithCGPoint:imgCentre];
anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
anim.duration = 0.3;
[img.layer addAnimation:anim forKey:#"rollLeft"];
img.frame = frame;
Due to some reason I wish to apply same animation but by using following type of approach:
[UIView animateWithDuration:0.3 delay:0.0 options:(UIViewAnimationOptionBeginFromCurrentState|UIViewAnimationOptionCurveEaseOut) animations:^{
...
} completion:^(BOOL finished) {
...
}
What I come up with is like following:
[img setCenter:imgCentre];
[UIView animateWithDuration:0.3 delay:0.0 options:(UIViewAnimationOptionBeginFromCurrentState|UIViewAnimationOptionCurveEaseOut) animations:^{
if (newValue == 0) {
CGPoint newPoint= CGPointMake(imgCentre.x, centerStart.y - 11 * kCounterDigitDiff);
[img setCenter:newPoint];
} else{
[img setCenter:imgCentre];
}
} completion:^(BOOL finished) {
// animation completion code
}];
img.frame = frame;
Overall things look good but I am a little bit pessimistic about the conversion? is there something that i have missed?
You've got the right idea. However, unlike with CAAnimations, you don't have to set the properties to the end value. The UIView animation call takes care of all that for you.
UIView animation is generally easier and more intuitive to use than CAAnimation.

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];
}
}];
}

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