iOS icon jiggle algorithm iOS icon jiggle algorithm ios ios

iOS icon jiggle algorithm



@Vic320's answer is good but personally I don't like the translation.I've edited his code to provide a solution that I personally feel looks more like the springboard wobble effect. Mostly, it's achieved by adding a little randomness and focusing on rotation, without translation:

#define degreesToRadians(x) (M_PI * (x) / 180.0)#define kAnimationRotateDeg 1.0- (void)startJiggling {    NSInteger randomInt = arc4random_uniform(500);    float r = (randomInt/500.0)+0.5;    CGAffineTransform leftWobble = CGAffineTransformMakeRotation(degreesToRadians( (kAnimationRotateDeg * -1.0) - r ));    CGAffineTransform rightWobble = CGAffineTransformMakeRotation(degreesToRadians( kAnimationRotateDeg + r ));     self.transform = leftWobble;  // starting point     [[self layer] setAnchorPoint:CGPointMake(0.5, 0.5)];     [UIView animateWithDuration:0.1                           delay:0                         options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse                       animations:^{                                  [UIView setAnimationRepeatCount:NSNotFound];                                 self.transform = rightWobble; }                      completion:nil];}- (void)stopJiggling {    [self.layer removeAllAnimations];    self.transform = CGAffineTransformIdentity;}


Credit where credit's due though, @Vic320's answer provided the basis for this code so +1 for that.


OK, so the openspringboard code didn't quite do it for me but I did allow me to create some code that I think is a bit better, still not prefect but better. If anyone has suggestions to make this better, I would love to hear them... (add this to the subclass of the view(s) you want to jiggle)

#define degreesToRadians(x) (M_PI * (x) / 180.0)#define kAnimationRotateDeg 1.0#define kAnimationTranslateX 2.0#define kAnimationTranslateY 2.0- (void)startJiggling:(NSInteger)count {    CGAffineTransform leftWobble = CGAffineTransformMakeRotation(degreesToRadians( kAnimationRotateDeg * (count%2 ? +1 : -1 ) ));    CGAffineTransform rightWobble = CGAffineTransformMakeRotation(degreesToRadians( kAnimationRotateDeg * (count%2 ? -1 : +1 ) ));    CGAffineTransform moveTransform = CGAffineTransformTranslate(rightWobble, -kAnimationTranslateX, -kAnimationTranslateY);    CGAffineTransform conCatTransform = CGAffineTransformConcat(rightWobble, moveTransform);    self.transform = leftWobble;  // starting point    [UIView animateWithDuration:0.1                          delay:(count * 0.08)                        options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse                     animations:^{ self.transform = conCatTransform; }                     completion:nil];}- (void)stopJiggling {    [self.layer removeAllAnimations];    self.transform = CGAffineTransformIdentity;  // Set it straight }


@mientus Original Apple Jiggle code in Swift 4, with optional parameters to adjust the duration (i.e. speed), displacement (i.e. position change) and degrees (i.e. rotation amount).

private func degreesToRadians(_ x: CGFloat) -> CGFloat {    return .pi * x / 180.0}func startWiggle(    duration: Double = 0.25,    displacement: CGFloat = 1.0,    degreesRotation: CGFloat = 2.0    ) {    let negativeDisplacement = -1.0 * displacement    let position = CAKeyframeAnimation.init(keyPath: "position")    position.beginTime = 0.8    position.duration = duration    position.values = [        NSValue(cgPoint: CGPoint(x: negativeDisplacement, y: negativeDisplacement)),        NSValue(cgPoint: CGPoint(x: 0, y: 0)),        NSValue(cgPoint: CGPoint(x: negativeDisplacement, y: 0)),        NSValue(cgPoint: CGPoint(x: 0, y: negativeDisplacement)),        NSValue(cgPoint: CGPoint(x: negativeDisplacement, y: negativeDisplacement))    ]    position.calculationMode = "linear"    position.isRemovedOnCompletion = false    position.repeatCount = Float.greatestFiniteMagnitude    position.beginTime = CFTimeInterval(Float(arc4random()).truncatingRemainder(dividingBy: Float(25)) / Float(100))    position.isAdditive = true    let transform = CAKeyframeAnimation.init(keyPath: "transform")    transform.beginTime = 2.6    transform.duration = duration    transform.valueFunction = CAValueFunction(name: kCAValueFunctionRotateZ)    transform.values = [        degreesToRadians(-1.0 * degreesRotation),        degreesToRadians(degreesRotation),        degreesToRadians(-1.0 * degreesRotation)    ]    transform.calculationMode = "linear"    transform.isRemovedOnCompletion = false    transform.repeatCount = Float.greatestFiniteMagnitude    transform.isAdditive = true    transform.beginTime = CFTimeInterval(Float(arc4random()).truncatingRemainder(dividingBy: Float(25)) / Float(100))    self.layer.add(position, forKey: nil)    self.layer.add(transform, forKey: nil)}