2011-07-06 32 views
18

Kullanıcı belgelerini, Sunumun onlara (gerçek belgenin büyük simgeleri olarak) sunma biçimine benzeyen bir iPad uygulaması yazıyorum. Ayrıca kullanıcı düzenleme düğmesine dokunduğunda jiggling davranışını taklit etmek istiyorum. Bu, iPhone ve iPad'de bunlara dokunup basılı tuttuğunuzda simgelerin ana ekranda oluşturduğu aynı jiggle desenidir.iOS simge jiggle algoritması

İnternette arama yaptım ve birkaç algoritma bulduk ama onlar sadece Apple jiggle gibi değil, ileri geri sallanmasına neden olur. Orada her simge biraz farklı şekilde jiggles olarak orada bazı rasgelelik var gibi görünüyor.

Aynı jiggle desenini (veya buna çok yakın bir şey) yeniden oluşturabilen bir kodun sahibi var mı? Teşekkürler!!!

cevap

12

Tamam, bu yüzden openspringboard kodu benim için tam olarak yapmadı, ama bence biraz daha iyi olduğunu düşündüğüm bir kod oluşturmama izin verdim, yine de daha iyi değil ama daha iyi. herkes bu daha iyi yapmak için bir öneriniz varsa Vic320 cevabı iyi ama @, ben ... bunları duymak

#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 
} 
3

openspringboard project'a bakın. Özellikle, SetIconAnimation: (BOOL) OpenSpringBoard.m öğesinde görüntüleniyor. Bu, bunun nasıl yapılacağı konusunda size bazı fikirler vermelidir.

32


(eğer titremeye istiyorum) bakış (s alt sınıfa bu ekleyin) isteriz Şahsen ben çeviri sevmiyorum. Kişisel olarak kendimi tramplen yalpalama etkisi gibi göründüğüm bir çözüm sağlamak için onun kodunu düzenledim. Çoğunlukla, bu çeviri olmadan, biraz rastlantısallığını eklenerek ve rotasyon odaklanarak elde ediyor: kredi nedeniyle olsa Vic320 cevabı @ bu kodu bunun için bu kadar +1 temel teşkil

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


kredi.

+0

çapa noktası 0.5,0.5 daha başka bir yerde, başka ayarlanırsa döndürme sabitleme noktasının çevresindeki düğmesi "bir yörüngeye" olur. Bu kendi başına serin bir etki olabilir :) –

+0

evet Alex! muhtemelen OP için cazip değil ama bu serin bir etki olurdu. – imnk

+1

Çift daha fazla puan: [UIView setAnimationRepeatCount: NSNotFound]; UIViewAnimationOptionRepeat ayarlandığı için gerekli değildir. Ve animasyonu durdurmak için şunu yapın: [self.layer removeAllAnimations]; – sdsykes

3

Gelecekte gelenlerin yararı için, Vic320 tarafından sunulan jiggle'ın biraz fazla robotik olduğunu ve Keynote ile karşılaştırmanın biraz fazla güçlü ve organik değil (rastgele?) Yeterli olduğunu hissettim. Paylaşım ruhu içinde, UIView alt sınıfımın içine yerleştirdiğim kod budur ... benim denetleyici denetleyicim bu nesnelerin bir dizisini tutar ve kullanıcı Düzenleme düğmesine dokunduğunda, görüntü denetleyicisi her birine startJiggling iletisini gönderir Kullanıcı Done düğmesine bastığında bir stopJiggling mesajıyla.

- (void)startJiggling 
{ 
    // jiggling code based off the folks on stackoverflow.com: 
    // http://stackoverflow.com/questions/6604356/ios-icon-jiggle-algorithm 

#define degreesToRadians(x) (M_PI * (x)/180.0) 
#define kAnimationRotateDeg 0.1 
    jiggling = YES; 
    [self wobbleLeft]; 
} 

- (void)wobbleLeft 
{ 
    if (jiggling) { 
     NSInteger randomInt = arc4random()%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 

     [UIView animateWithDuration:0.1 
         delay:0 
        options:UIViewAnimationOptionAllowUserInteraction 
       animations:^{ self.transform = rightWobble; } 
       completion:^(BOOL finished) { [self wobbleRight]; } 
      ]; 
    } 
} 

- (void)wobbleRight 
{ 
    if (jiggling) { 

     NSInteger randomInt = arc4random()%500; 
     float r = (randomInt/500.0)+0.5; 

     CGAffineTransform leftWobble = CGAffineTransformMakeRotation(degreesToRadians((kAnimationRotateDeg * -1.0) - r)); 
     CGAffineTransform rightWobble = CGAffineTransformMakeRotation(degreesToRadians(kAnimationRotateDeg + r)); 

     self.transform = rightWobble; // starting point 

     [UIView animateWithDuration:0.1 
         delay:0 
        options:UIViewAnimationOptionAllowUserInteraction 
       animations:^{ self.transform = leftWobble; } 
       completion:^(BOOL finished) { [self wobbleLeft]; } 
     ]; 
    } 

} 
- (void)stopJiggling 
{ 
    jiggling = NO; 
    [self.layer removeAllAnimations]; 
    [self setTransform:CGAffineTransformIdentity]; 
    [self.layer setAnchorPoint:CGPointMake(0.5, 0.5)]; 
} 
2

Yani (Ben yarı acemi olduğum için farkında değilim bunu yapmak için muhtemelen daha basit yolları vardır) dağınık kod yazmak için bağırdı eminim, ama bu rotasyon ve çeviri miktarını değiştiren Vic320'nin algoritmasının daha rasgele bir versiyonu. Aynı zamanda hangi yöne titreyeceğine de karar verir, aynı anda birden fazla şeyiniz varsa çok daha rastgele bir görünüm verir. Verimlilik sizin için büyük bir problemse, kullanmayın. Bu, nasıl yapılacağını bildiğim yolla geldiğim şey.

#import <QuartzCore/QuartzCore.h>'a gereksinim duyduğunuzu ve bunun sizin bağlantılı kitaplıklarınıza eklemeniz gerektiğini merak eden herkes için. Diğer cevaplar esinlenerek - - açık animasyon kullanarak

#define degreesToRadians(x) (M_PI * (x)/180.0) 

- (void)startJiggling:(NSInteger)count { 
    double kAnimationRotateDeg = (double)(arc4random()%5 + 5)/10; 
    double kAnimationTranslateX = (arc4random()%4); 
    double kAnimationTranslateY = (arc4random()%4); 

    CGAffineTransform leftWobble = CGAffineTransformMakeRotation(degreesToRadians(kAnimationRotateDeg * (count%2 ? +1 : -1))); 
    CGAffineTransform rightWobble = CGAffineTransformMakeRotation(degreesToRadians(kAnimationRotateDeg * (count%2 ? -1 : +1))); 
    int leftOrRight = (arc4random()%2); 
    if (leftOrRight == 0){ 
     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]; 
    } else if (leftOrRight == 1) { 
     CGAffineTransform moveTransform = CGAffineTransformTranslate(leftWobble, -kAnimationTranslateX, -kAnimationTranslateY); 
     CGAffineTransform conCatTransform = CGAffineTransformConcat(leftWobble, moveTransform); 
     self.transform = rightWobble; // 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 
} 
+0

Seçtiğiniz jiggling yapmaya hangi yöne doğru rasgele seçmeyi seviyorum. Ben kodumu benzer şekilde güncellemek gidiyorum! – tobinjim

6

tamlığı için buraya benim CALayer alt sınıf animasyonlu nasıl.

-(void)stopJiggle 
{ 
    [self removeAnimationForKey:@"jiggle"]; 
} 

-(void)startJiggle 
{ 
    const float amplitude = 1.0f; // degrees 
    float r = (rand()/(float)RAND_MAX) - 0.5f; 
    float angleInDegrees = amplitude * (1.0f + r * 0.1f); 
    float animationRotate = angleInDegrees/180. * M_PI; // Convert to radians 

    NSTimeInterval duration = 0.1; 
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"]; 
    animation.duration = duration; 
    animation.additive = YES; 
    animation.autoreverses = YES; 
    animation.repeatCount = FLT_MAX; 
    animation.fromValue = @(-animationRotate); 
    animation.toValue = @(animationRotate); 
    animation.timeOffset = (rand()/(float)RAND_MAX) * duration; 
    [self addAnimation:animation forKey:@"jiggle"]; 
} 
2

Apple Stringboard mühendislik ve biraz da animasyon modifiye ve kod aşağıda gerçekten iyi şeyler ters.

+ (CAAnimationGroup *)jiggleAnimation { 
CAKeyframeAnimation *position = [CAKeyframeAnimation animation]; 
position.keyPath = @"position"; 
position.values = @[ 
        [NSValue valueWithCGPoint:CGPointZero], 
        [NSValue valueWithCGPoint:CGPointMake(-1, 0)], 
        [NSValue valueWithCGPoint:CGPointMake(1, 0)], 
        [NSValue valueWithCGPoint:CGPointMake(-1, 1)], 
        [NSValue valueWithCGPoint:CGPointMake(1, -1)], 
        [NSValue valueWithCGPoint:CGPointZero] 
        ]; 
position.timingFunctions = @[ 
          [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut], 
          [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut] 
          ]; 
position.additive = YES; 

CAKeyframeAnimation *rotation = [CAKeyframeAnimation animation]; 
rotation.keyPath = @"transform.rotation"; 
rotation.values = @[ 
        @0, 
        @0.03, 
        @0, 
        [NSNumber numberWithFloat:-0.02] 
        ]; 
rotation.timingFunctions = @[ 
          [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut], 
          [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut] 
          ]; 

CAAnimationGroup *group = [[CAAnimationGroup alloc] init]; 
group.animations = @[ position, rotation ]; 
group.duration = 0.3; 
group.repeatCount = HUGE_VALF; 
group.beginTime = arc4random() % 30/100.f; 
return group; 
} 

Orijinal Apple çalkala animasyon: Swift 4 Orijinal Apple çalkala kodu @mientus

CAKeyframeAnimation *position = [CAKeyframeAnimation animation]; 
position.beginTime = 0.8; 
position.duration = 0.25; 
position.values = @[[NSValue valueWithCGPoint:CGPointMake(-1, -1)], 
        [NSValue valueWithCGPoint:CGPointMake(0, 0)], 
        [NSValue valueWithCGPoint:CGPointMake(-1, 0)], 
        [NSValue valueWithCGPoint:CGPointMake(0, -1)], 
        [NSValue valueWithCGPoint:CGPointMake(-1, -1)]]; 
position.calculationMode = @"linear"; 
position.removedOnCompletion = NO; 
position.repeatCount = CGFLOAT_MAX; 
position.beginTime = arc4random() % 25/100.f; 
position.additive = YES; 
position.keyPath = @"position"; 

CAKeyframeAnimation *transform = [CAKeyframeAnimation animation]; 
transform.beginTime = 2.6; 
transform.duration = 0.25; 
transform.valueFunction = [CAValueFunction functionWithName:kCAValueFunctionRotateZ]; 
transform.values = @[@(-0.03525565),@(0.03525565),@(-0.03525565)]; 
transform.calculationMode = @"linear"; 
transform.removedOnCompletion = NO; 
transform.repeatCount = CGFLOAT_MAX; 
transform.additive = YES; 
transform.beginTime = arc4random() % 25/100.f; 
transform.keyPath = @"transform"; 

[self.dupa.layer addAnimation:position forKey:nil]; 
[self.dupa.layer addAnimation:transform forKey:nil]; 
+0

Aman tanrım seni seviyorum, bu harika – Jota

2

, isteğe bağlı süresi (yani hız), yer değiştirme (örneğin, konum değişikliği) ayarlamak için parametreler ve derece ile (yani dönme miktarı).

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