Animate button two Labels Text change - ios

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.

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()
}

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

Can I rotate UIImage around the centre with animation?

I want to rotate image in circular animation. How can I do it in a simple way?
I know it is not difficult but I'm new to iOS.
Can anybody tell me right code ?
its my solution:
- (void)startAnimation
{
[UIView animateWithDuration:.4 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
[self.loadingRingImageView setTransform:CGAffineTransformRotate(self.loadingRingImageView.transform, M_SQRT2)];
} completion:^(BOOL finished) {
if (finished)
{
[self startAnimation];
}
}];
}
[[self.<imageviewinstance> layer] addAnimation:[self rotationAnimation] forKey:nil];
Add the animation as above and the below is the animation code.
- (CABasicAnimation *)rotationAnimation
{
CABasicAnimation *rotAnim = [CABasicAnimation animationWithKeyPath:#"position"];
[rotAnim setFromValue:[NSValue valueWithCGPoint:CGPointMake(100.0, 400.0)]];
rotAnim.toValue = [NSValue valueWithCGPoint:CGPointMake(300.0, 150.0)];
// rotAnim.duration = 5.0;
rotAnim.autoreverses = YES;
// rotAnim.repeatCount = HUGE_VAL;
rotAnim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
return rotAnim;
}
if the above is not worked use this
- (CABasicAnimation *)rotationAnimation
{
CABasicAnimation *move = [CABasicAnimation animationWithKeyPath:#"transform.rotation" ];
move.delegate = self;
[move setFromValue:[NSNumber numberWithFloat:0]];
[move setToValue:[NSNumber numberWithFloat:50]];
[move setDuration:10.0f];
move.autoreverses = YES;
}
the answer of question i was wondering is ->
UIImageView *imageViewForAnimation = [[UIImageView alloc] initWithImage:imageToAnimate];
imageViewForAnimation.alpha = 1.0f;
CGRect imageFrame = imageViewForAnimation.frame;
//Your image frame.origin from where the animation need to get start
CGPoint viewOrigin = imageViewForAnimation.frame.origin;
viewOrigin.y = viewOrigin.y + imageFrame.size.height / 2.0f;
viewOrigin.x = viewOrigin.x + imageFrame.size.width / 2.0f;
imageViewForAnimation.frame = imageFrame;
imageViewForAnimation.layer.position = viewOrigin;
[self.view addSubview:imageViewForAnimation];
// Set up fade out effect
CABasicAnimation *fadeOutAnimation = [CABasicAnimation animationWithKeyPath:#"opacity"];
[fadeOutAnimation setToValue:[NSNumber numberWithFloat:0.3]];
fadeOutAnimation.fillMode = kCAFillModeForwards;
fadeOutAnimation.removedOnCompletion = NO;
// Set up scaling
CABasicAnimation *resizeAnimation = [CABasicAnimation animationWithKeyPath:#"bounds.size"];
[resizeAnimation setToValue:[NSValue valueWithCGSize:CGSizeMake(40.0f, imageFrame.size.height * (40.0f / imageFrame.size.width))]];
resizeAnimation.fillMode = kCAFillModeForwards;
resizeAnimation.removedOnCompletion = NO;
// Set up path movement
CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:#"position"];
pathAnimation.calculationMode = kCAAnimationPaced;
pathAnimation.fillMode = kCAFillModeForwards;
pathAnimation.removedOnCompletion = NO;
//Setting Endpoint of the animation
CGPoint endPoint = CGPointMake(480.0f - 30.0f, 40.0f);
//to end animation in last tab use
//CGPoint endPoint = CGPointMake( 320-40.0f, 480.0f);
CGMutablePathRef curvedPath = CGPathCreateMutable();
CGPathMoveToPoint(curvedPath, NULL, viewOrigin.x, viewOrigin.y);
CGPathAddCurveToPoint(curvedPath, NULL, endPoint.x, viewOrigin.y, endPoint.x, viewOrigin.y, endPoint.x, endPoint.y);
pathAnimation.path = curvedPath;
CGPathRelease(curvedPath);
CAAnimationGroup *group = [CAAnimationGroup animation];
group.fillMode = kCAFillModeForwards;
group.removedOnCompletion = NO;
[group setAnimations:[NSArray arrayWithObjects:fadeOutAnimation, pathAnimation, resizeAnimation, nil]];
group.duration = 0.7f;
group.delegate = self;
[group setValue:imageViewForAnimation forKey:#"imageViewBeingAnimated"];
[imageViewForAnimation.layer addAnimation:group forKey:#"savingAnimation"];

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

UIView shake animation

i'm trying to make a UIView shake when a button is pressed.
I am adapting the code I found on http://www.cimgf.com/2008/02/27/core-animation-tutorial-window-shake-effect/.
However, by trying to adapt the following code to shake a UIView, it does not work:
- (void)animate {
const int numberOfShakes = 8;
const float durationOfShake = 0.5f;
const float vigourOfShake = 0.1f;
CAKeyframeAnimation *shakeAnimation = [CAKeyframeAnimation animation];
CGRect frame = lockView.frame;
CGMutablePathRef shakePath = CGPathCreateMutable();
CGPathMoveToPoint(shakePath, NULL, CGRectGetMinX(frame), CGRectGetMinY(frame));
for (int index = 0; index < numberOfShakes; ++index) {
CGPathAddLineToPoint(shakePath, NULL, CGRectGetMinX(frame) - frame.size.width * vigourOfShake, CGRectGetMinY(frame));
CGPathAddLineToPoint(shakePath, NULL, CGRectGetMinX(frame) + frame.size.width * vigourOfShake, CGRectGetMinY(frame));
}
CGPathCloseSubpath(shakePath);
shakeAnimation.path = shakePath;
shakeAnimation.duration = durationOfShake;
[lockView.layer addAnimation:shakeAnimation forKey:#"frameOrigin"];
}
I wrote that post. It's overkill for a UIView, plus the parameters are geared toward an OSX app. Do this instead.
CABasicAnimation *animation =
[CABasicAnimation animationWithKeyPath:#"position"];
[animation setDuration:0.05];
[animation setRepeatCount:8];
[animation setAutoreverses:YES];
[animation setFromValue:[NSValue valueWithCGPoint:
CGPointMake([lockView center].x - 20.0f, [lockView center].y)]];
[animation setToValue:[NSValue valueWithCGPoint:
CGPointMake([lockView center].x + 20.0f, [lockView center].y)]];
[[lockView layer] addAnimation:animation forKey:#"position"];
You'll have to play with the duration and repeatCount parameters as well as the x distance from center in the from and to values, but it should give you what you need.
Swift 3.0
let midX = lockView.center.x
let midY = lockView.center.y
let animation = CABasicAnimation(keyPath: "position")
animation.duration = 0.06
animation.repeatCount = 4
animation.autoreverses = true
animation.fromValue = CGPoint(x: midX - 10, y: midY)
animation.toValue = CGPoint(x: midX + 10, y: midY)
layer.add(animation, forKey: "position")
I prefer this solution that has a nice springy behavior, ideal for a wrong-password shake animation.
view.transform = CGAffineTransformMakeTranslation(20, 0);
[UIView animateWithDuration:0.4 delay:0.0 usingSpringWithDamping:0.2 initialSpringVelocity:1.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
view.transform = CGAffineTransformIdentity;
} completion:nil];
Swift 3
extension UIView {
func shake() {
self.transform = CGAffineTransform(translationX: 20, y: 0)
UIView.animate(withDuration: 0.4, delay: 0, usingSpringWithDamping: 0.2, initialSpringVelocity: 1, options: .curveEaseInOut, animations: {
self.transform = CGAffineTransform.identity
}, completion: nil)
}
}
Here's my nice and simple looking version This simulates the shake you get on Mac OS X when you do an incorrect login. You could add this as a category on UIView if you like.
#implementation UIView (DUExtensions)
- (void) shake {
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:#"transform.translation.x"];
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
animation.duration = 0.6;
animation.values = #[ #(-20), #(20), #(-20), #(20), #(-10), #(10), #(-5), #(5), #(0) ];
[self.layer addAnimation:animation forKey:#"shake"];
}
#end
The animation values are the x offset from the views current position. Positive values shifting the view to the right, and negative values to the left. By successively lowering them, you get a shake that naturally loses momentum. You can tweak these numbers if you like.
Here is the swift version as an extension in case anybody needs it
extension UIImageView{
func vibrate(){
let animation = CABasicAnimation(keyPath: "position")
animation.duration = 0.05
animation.repeatCount = 5
animation.autoreverses = true
animation.fromValue = NSValue(CGPoint: CGPointMake(self.center.x - 2.0, self.center.y))
animation.toValue = NSValue(CGPoint: CGPointMake(self.center.x + 2.0, self.center.y))
self.layer.addAnimation(animation, forKey: "position")
}
}
This will animate an small UIImageView (around 15x15). If you need to animate something bigger you may want to change the 2.0 factor of movement to something greater.
Based on #bandejapaisa answer, UIView extension for Swift 3
extension UIView {
func shake() {
let animation = CAKeyframeAnimation(keyPath: "transform.translation.x")
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
animation.duration = 0.6
animation.values = [-20, 20, -20, 20, -10, 10, -5, 5, 0]
layer.addAnimation(animation, forKey: "shake")
}
}
You can try this piece of code:
to call the code below, use: [self earthquake:myObject];
#pragma mark EarthQuake Methods
- (void)earthquake:(UIView*)itemView
{
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
CGFloat t = 2.0;
CGAffineTransform leftQuake = CGAffineTransformTranslate(CGAffineTransformIdentity, t, -t);
CGAffineTransform rightQuake = CGAffineTransformTranslate(CGAffineTransformIdentity, -t, t);
itemView.transform = leftQuake; // starting point
[UIView beginAnimations:#"earthquake" context:itemView];
[UIView setAnimationRepeatAutoreverses:YES]; // important
[UIView setAnimationRepeatCount:3];
[UIView setAnimationDuration:0.05];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(earthquakeEnded:finished:context:)];
itemView.transform = rightQuake; // end here & auto-reverse
[UIView commitAnimations];
}
- (void)earthquakeEnded:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
{
if ([finished boolValue])
{
UIView* item = (UIView *)context;
item.transform = CGAffineTransformIdentity;
}
}
You can call this method on UIButton click event
-(void)shakescreen
{
//Shake screen
CGFloat t = 5.0;
CGAffineTransform translateRight = CGAffineTransformTranslate(CGAffineTransformIdentity, t, t);
CGAffineTransform translateLeft = CGAffineTransformTranslate(CGAffineTransformIdentity, -t, -t);
self.view.transform = translateLeft;
[UIView animateWithDuration:0.05 delay:0.0 options:UIViewAnimationOptionAutoreverse|UIViewAnimationOptionRepeat animations:^
{
[UIView setAnimationRepeatCount:2.0];
self.view.transform = translateRight;
} completion:^(BOOL finished)
{
if (finished)
{
[UIView animateWithDuration:0.05 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^
{
self.view.transform = CGAffineTransformIdentity;
}
completion:NULL];
}
}];
}
Hope this will help you :-)
C# Xamarin.iOS version of answer how to create UIView shake animation in iOS is below
CAKeyFrameAnimation keyframeAnimation = CAKeyFrameAnimation.GetFromKeyPath(new NSString("transform.translation.x"));
keyframeAnimation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut);
keyframeAnimation.Duration = 0.6f;
keyframeAnimation.Values = new NSObject[]{ new NSNumber(-20f), new NSNumber(20f), new NSNumber(-20f), new NSNumber(20f), new NSNumber(-10f), new NSNumber(10f), new NSNumber(-5f), new NSNumber(5f), new NSNumber(0f) };
shakyView.Layer.AddAnimation(keyframeAnimation, "shake");
#imike answer in Swift 4.2
extension UIView {
func shake() {
let animation = CAKeyframeAnimation(keyPath: "transform.translation.x")
animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
animation.duration = 0.6
animation.values = [-20, 20, -20, 20, -10, 10, -5, 5, 0]
self.layer.add(animation, forKey: "shake")
}}
Here's one that uses a damper function to decay the shake:
- (void)shake
{
CAKeyframeAnimation* animation = [CAKeyframeAnimation animationWithKeyPath:#"position"];
animation.duration = 0.5;
animation.delegate = self;
animation.fillMode = kCAFillModeForwards;
animation.removedOnCompletion = YES;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
NSMutableArray* values = [[NSMutableArray alloc] init];
int steps = 100;
double position = 0;
float e = 2.71;
for (int t = 0; t < steps; t++)
{
position = 10 * pow(e, -0.022 * t) * sin(0.12 * t);
NSValue* value = [NSValue valueWithCGPoint:CGPointMake([self center].x - position, [self center].y)];
DDLogInfo(#"Value: %#", value);
[values addObject:value];
}
animation.values = values;
[[self layer] addAnimation:animation forKey:#"position"];
}
I refactored #Matt Long code and made a category to UIView. Now it's much more reusable and easy to use.
#implementation UIView (Animation)
- (void)shakeViewWithOffest:(CGFloat)offset {
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:#"position.x"];
[animation setDuration:0.05];
[animation setRepeatCount:6];
[animation setAutoreverses:YES];
[animation setFromValue:#([self center].x-offset)];
[animation setToValue:#([self center].x+offset)];
[self.layer addAnimation:animation forKey:#"position.x"];
}
- (void)shake {
[self shakeViewWithOffest:7.0f];
}
#end
Swift 3 implementation based on #Mihael-Isaev answer
private enum Axis: StringLiteralType {
case x = "x"
case y = "y"
}
extension UIView {
private func shake(on axis: Axis) {
let animation = CAKeyframeAnimation(keyPath: "transform.translation.\(axis.rawValue)")
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
animation.duration = 0.6
animation.values = [-20, 20, -20, 20, -10, 10, -5, 5, 0]
layer.add(animation, forKey: "shake")
}
func shakeOnXAxis() {
self.shake(on: .x)
}
func shakeOnYAxis() {
self.shake(on: .y)
}
}
Swift 4.0:
Based on the top answer but a refinement over the animation: This does not have the jumps at the start and end of animation.
let midX = center.x
let midY = center.y
let rightAnim = CABasicAnimation(keyPath: #keyPath(CALayer.position))
rightAnim.duration = 0.07
rightAnim.autoreverses = true
rightAnim.fromValue = CGPoint(x: midX, y: midY)
rightAnim.toValue = CGPoint(x: midX + 9, y: midY)
let leftAnim = CABasicAnimation(keyPath: #keyPath(CALayer.position))
leftAnim.duration = 0.07
leftAnim.autoreverses = true
leftAnim.fromValue = CGPoint(x: midX, y: midY)
leftAnim.toValue = CGPoint(x: midX - 9, y: midY)
let group = CAAnimationGroup()
group.duration = leftAnim.duration + rightAnim.duration
group.animations = [rightAnim, leftAnim]
group.repeatCount = 3
layer.add(group, forKey: #keyPath(CALayer.position))
You can try the following code:
+ (void)vibrateView:(UIView*)view
{
CABasicAnimation *shiverAnimationR;
shiverAnimationR = [CABasicAnimation animationWithKeyPath:#"transform.rotation.z"];
shiverAnimationR.toValue = [NSNumber numberWithFloat:DEGREES_TO_RADIANS(1)];
//shiverAnimationR.toValue = [NSNumber numberWithFloat:DEGREES_TO_RADIANS(-10)];
shiverAnimationR.duration = 0.1;
shiverAnimationR.repeatCount = 1000000.0; // Use A high Value
shiverAnimationR.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
[view.layer addAnimation: shiverAnimationR forKey:#"shiverAnimationR"];
CABasicAnimation * shiverAnimationL;
shiverAnimationL = [CABasicAnimation animationWithKeyPath:#"transform.rotation.z"];
//shiverAnimationL 2.toValue = [NSNumber numberWithFloat:DEGREES_TO_RADIANS(10)];
shiverAnimationL.toValue = [NSNumber numberWithFloat:DEGREES_TO_RADIANS(-1)];
shiverAnimationL.duration = 0.1;
shiverAnimationL.repeatCount = 1000000.0;
shiverAnimationL.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
[view.layer addAnimation: shiverAnimationL forKey:#"shiverAnimationL"];
}
From the link.
Here is a version using,
+ (void)animateKeyframesWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewKeyframeAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion
Introduced in iOS 7.
const CGFloat xDelta = 16.0f;
[UIView animateKeyframesWithDuration:0.50f
delay:0.0f
options:UIViewKeyframeAnimationOptionCalculationModeLinear
animations:^{
[UIView addKeyframeWithRelativeStartTime:0.0
relativeDuration:(1.0/6.0)
animations:^{
self.passwordTextField.transform = self.usernameTextField.transform = CGAffineTransformMakeTranslation(xDelta, 0.0);
}];
[UIView addKeyframeWithRelativeStartTime:(1.0/6.0)
relativeDuration:(1.0/6.0)
animations:^{
self.passwordTextField.transform = self.usernameTextField.transform = CGAffineTransformMakeTranslation(-xDelta, 0.0);
}];
[UIView addKeyframeWithRelativeStartTime:(1.0/3.0)
relativeDuration:(1.0/3.0)
animations:^{
self.passwordTextField.transform = self.usernameTextField.transform = CGAffineTransformMakeTranslation(xDelta/2.0, 0.0);
}];
[UIView addKeyframeWithRelativeStartTime:(2.0/3.0)
relativeDuration:(1.0/3.0)
animations:^{
self.passwordTextField.transform = self.usernameTextField.transform = CGAffineTransformIdentity;
}];
}
completion:NULL];
Here is a UIView extension providing an awesome shake animation: https://gist.github.com/mourad-brahim/cf0bfe9bec5f33a6ea66
A Swift5 update is provided on the comments.

Resources