Spin and move UIView - ios

How to move continuously spinning UIView with animation blocks? Eg., I have this code for spinning:
- (void)spinView:(UIView *)view {
[UIView animateWithDuration:0.2f
delay:0.0f
options:UIViewAnimationOptionCurveLinear
animations:^{
view.transform = CGAffineTransformRotate(view.transform, M_PI_2);
}
completion:^(BOOL finished) {
if (finished) {
[self spinView:view];
}
}];
}
How to combine it with animation like this:
[UIView animateWithDuration:4.0f animations:^{
myView.transform = CGAffineTransformTranslate(myView.transform, 400, 0);
}];
I've tried with CGAffineTransformConcat(), UIViewAnimationOptionBeginFromCurrentState, but without success.

Have you try something like,
[UIView animateWithDuration:2.0f animations:^{
vw.transform = CGAffineTransformTranslate(vw.transform, 400, 0);
CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath:#"transform.rotation.z"];
animation.fromValue = [NSNumber numberWithFloat:0.0f];
animation.toValue = [NSNumber numberWithFloat: 2*M_PI];
animation.duration = 5.0f;
animation.repeatCount = 1;
[vw.layer addAnimation:animation forKey:#"SpinAnimation"];
}];
vw is your view to move. set frame according to your wish.

Related

UIView Animation is far from smooth

I am trying to scale a button up and down to call attention to it.
I have tried two animation methods:
method 1
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:#"transform.scale"];
animation.autoreverses = YES;
animation.repeatDuration = 2;
animation.duration = 0.4;
animation.fromValue = #(1.0f);
animation.toValue= #(1.2f);
[button.layer addAnimation:animation forKey:#"scale"];
method 2
CGAffineTransform scaleUp = CGAffineTransformMakeScale(1.2f, 1.2f);
[UIView animateWithDuration:0.5 delay:1 options:UIViewAnimationOptionAutoreverse
animations:^{
[button setTransform:scaleUp];
} completion:^(BOOL finished) {
}];
Same problem with both animations. Near the end, when the button is scaling down to its normal scale, the animation jumps directly to scale 1.0.
Something like:
1.2 ... 1.18 ... 1.15 ... boom ... 1.0
and I see the button popping from one huge scale value to 1, instead of being smooth.
You need to set the final state of the button.In your case,the scale change like
1.0->1.1->1.2->1.1->1.0 ->1.2(jump to final state)
Gif
CGAffineTransform scaleUp = CGAffineTransformMakeScale(1.5f, 1.5f);
[UIView animateWithDuration:0.5 delay:1 options:UIViewAnimationOptionAutoreverse
animations:^{
[self.button setTransform:scaleUp];
} completion:^(BOOL finished) {
self.button.transform = CGAffineTransformIdentity;
}];

Creating Animation for search

I am writing an animation for my search button, so when the user clicks on search I want to make a transition on my button and then move it to left and push the search view on it's back. I am trying to use the following code:
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:#"transform.rotation.z"];
animation.repeatDuration = 1000;
animation.duration = 30;
animation.additive = YES;
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeBoth;
animation.fromValue = [NSNumber numberWithFloat:0];
animation.toValue = [NSNumber numberWithFloat:360];
[self.SearchButton.layer addAnimation:animation forKey:#"rotationAnimation"];
[CATransaction begin]; {
[CATransaction setCompletionBlock:^{
[UIView animateWithDuration:0.6 delay:2 options:UIViewAnimationOptionCurveEaseIn animations:^{
[self.SearchButton setFrame:CGRectMake(self.slideMenuButton.frame.origin.x, self.slideMenuButton.frame.origin.y, self.SearchButton.frame.size.width, self.SearchButton.frame.size.height)];
[UIView animateWithDuration:0.6 delay:10.f options:UIViewAnimationOptionCurveEaseIn animations:^{
[self.navigationController presentViewController:Search animated:YES completion:nil];
}completion:^(BOOL finished) {
[self.SearchButton setFrame:CGRectMake(searchOrigin.x, searchOrigin.y, self.SearchButton.frame.size.width, self.SearchButton.frame.size.height)];
}];
} completion:^(BOOL finished) {
[self.SearchButton.layer removeAnimationForKey:#"rotationAnimation"];
}];
}];
}
Each animation is working correctly but I want them to follow each other so the feeling of movements be good. It means I want the button to do a transition and then move to the new point and the new view push to my view by following that.
It would be appreciated if you help me or give me any idea so I can implement that.

How to convert a CABasicAnimation to UIView animatewithDuration

I want to convert a CABasicAnimation to UIView animatewithDuration , If there is any possible to do that?
This is my tried code so far
CABasicAnimation *myAni = [CABasicAnimation animationWithKeyPath:#"transform.scale.x"];
myAni.duration = 2.0f;
myAni.fromValue = [NSNumber numberWithFloat:1.0];
myAni.toValue = [NSNumber numberWithFloat:2.0];
[self.myView addAnimation:scaleAnimation forKey:#"myKey"];
to be in [UIView animateWithDuration.... (Instead of CABasicAnimation, I want it in animationWithDuration in the animations block.)
Is this possible? If so, how?
[UIView animateWithDuration:0.5
delay:1.0
options: UIViewAnimationCurveEaseOut
animations:^{
//I need it here
}
completion:^(BOOL finished){
}];
Thanks in advance
[UIView animateWithDuration:0.5
delay:1.0
options: UIViewAnimationOptionCurveEaseInOut
animations:^{
//self.myView.transform = CGAffineTransformMakeScale(2.0,1.0);
self.testview.layer.transform = CATransform3DMakeScale(2.0,1.0,1.0);
}
completion:^(BOOL finished){
}];

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

Resources