53 Stimmen

Wie erzeugt man den wackelnden Icon-Effekt für das iPhone?

Ich möchte ein Bild in meiner Anwendung hin und her wackeln lassen, ähnlich wie die iPhone-Symbole wackeln, wenn man sie nach unten drückt. Wie kann ich das am besten machen?

Dies ist mein erster Ausflug in die Welt der Animationen, bei dem ich keine animierten GIFs verwende. Ich glaube, die Idee ist, das Bild leicht hin und her zu drehen, um den Wackeleffekt zu erzeugen. Ich habe die Verwendung von CABasicAnimation und CAKeyframeAnimation in Betracht gezogen. CABasicAnimation erzeugt bei jeder Wiederholung einen Jitter, weil es zur Ausgangsposition springt und nicht zurück interpoliert. CAKeyframeAnimation scheint wie die Lösung, außer dass ich es nicht zum Laufen bringen kann. Ich muss etwas übersehen. Hier ist mein Code mit der CAKeyframeAnimation (die nicht funktioniert):

    NSString *keypath = @"wobbleImage";
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:keypath];
animation.duration = 1.0f;
animation.delegate = self;
animation.repeatCount = 5;

CGFloat wobbleAngle = 0.0872664626f;
NSValue *initial = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(0.0f, 0.0f, 0.0f, 1.0f)];
NSValue *middle = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(wobbleAngle, 0.0f, 0.0f, 1.0f)];
NSValue *final = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(-wobbleAngle, 0.0f, 0.0f, 1.0f)];
animation.values = [NSArray arrayWithObjects:initial, middle, final, nil];

[imageView.layer addAnimation:animation forKey:keypath];

Vielleicht gibt es aber auch eine ganz einfache Lösung, die ich gerade übersehe. Ich bin für jeden Hinweis dankbar. Danke!

2voto

Thanks Punkte 39529

Der einfachste Weg, den ich kenne, ist die Verwendung von Core Animation. Grundsätzlich erstellen Sie einen Core Animation Block, dann tun Sie eine Rotation transformieren und Setup und Wiederholung zählen. Core Animation kümmert sich dann um alles, was nötig ist, um diesen Wobbling-Effekt zu erzielen.

Um einen Core Animation-Block zu starten, tun Sie einfach:

[UIView beginAnimations:@"any string as animationID" context:self];
[UIView setAnimationRepeatCount:10];
// rotate 
[UIView commitAnimations];

nicht getestet. Aber es kann sein, dass Sie auch zu tun haben werden:

[UIView setAnimationBeginsFromCurrentState:YES];

A.F.A.I.K. setAnimationRepeatCount bewirkt, dass die Animation so oft ausgeführt, rückgängig gemacht, ausgeführt, rückgängig gemacht, ausgeführt, rückgängig gemacht, ausgeführt... wird, wie Sie angeben. Sie können also zunächst ohne Wiederholungszähler nach links drehen und dann von diesem Punkt aus mit Wiederholungszähler anfangen zu wackeln. Wenn Sie fertig sind, möchten Sie vielleicht zur Identitätstransformation zurückdrehen (= keine Drehung und Skalierung angewendet).

Sie können Animationen verketten, indem Sie den Animationsdelegaten mit

[UIView setAnimationDelegate:self]

und dann

[UIView setAnimationDidStopSelector:@selector(myMethod:finished:context:)];

und sobald die Animation stoppt, wird diese Methode aufgerufen. In der Dokumentation der Klasse UIView ist beschrieben, wie die Methode implementiert wird, die aufgerufen wird, wenn die Animation stoppt. Grundsätzlich würden Sie innerhalb dieser Methode den nächsten Schritt ausführen (d. h. zurückdrehen oder etwas anderes), mit einem neuen Animationsblock, aber demselben Kontext und derselben Animations-ID, und dann (falls erforderlich) einen weiteren didStopSelector angeben.

UPDATE:

Das könnte Sie interessieren:

[UIView setAnimationRepeatAutoreverses:YES];

wackelt dieser automatisch hin und her.

2voto

Berik Punkte 7536

Sie können einen nicht endlosen Wobble-Effekt erzeugen, indem Sie die CAKeyframeAnimation , etwa so:

CGFloat degrees = 8.0;
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"];
animation.duration = 0.6;
animation.cumulative = YES;
animation.repeatCount = 1;
animation.values = @[@0.0,
                    @RADIANS(-degrees) * 0.25,
                    @0.0,
                    @RADIANS(degrees) * 0.5,
                    @0.0,
                    @RADIANS(-degrees),
                    @0.0,
                    @RADIANS(degrees),
                    @0.0,
                    @RADIANS(-degrees) * 0.5,
                    @0.0,
                    @RADIANS(degrees) * 0.25,
                    @0.0];
animation.fillMode = kCAFillModeForwards;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
animation.removedOnCompletion = YES;

[self.layer addAnimation:animation forKey:@"wobble"];

2voto

Jagie Punkte 2112

Aus den obigen Antworten geht hervor, dass ich die Swift5-Version habe:

  func startWobble() {
    let angle = 5.0 * Double.pi / 180.0;
    self.transform = CGAffineTransform.identity.rotated(by: CGFloat(-angle));
    UIView.animate(withDuration: 0.25, delay: 0, options: [.allowUserInteraction,.repeat,.autoreverse], animations: {
         self.transform = CGAffineTransform.identity.rotated(by: CGFloat(angle));
    }, completion: nil)

}

func stopWobble() {

    UIView.animate(withDuration: 0.25, delay: 0, options: [.allowUserInteraction,.beginFromCurrentState,.curveLinear], animations: {
        self.transform = CGAffineTransform.identity;
    }, completion: nil)
}

1voto

EsbenB Punkte 3346

Ich komme zu spät zur Party. Ich bin in der Regel mit Feder mit Dämpfung (iOS7 und neuere). In Swift sieht es so aus:

    sender.transform = CGAffineTransformMakeScale(1.2, 1.2)
    UIView.animateWithDuration(0.30, delay: 0.0, usingSpringWithDamping: 0.3, initialSpringVelocity: 0.3, options: UIViewAnimationOptions.CurveEaseInOut, animations: { () -> Void in
        sender.transform = CGAffineTransformMakeScale(1, 1)
    }) { (Bool) -> Void in
    //Do stuff when animation is finished
    }

Sie können den Effekt durch Anpassen der initialSpringVelocity y SpringWithDamping

1voto

user599849 Punkte 21

Basierend auf der Antwort von EsbenB, aber aktualisiert für Swift 3 und für Rotation:

    sender.transform = CGAffineTransform(rotationAngle: 12.0 * .pi / 180.0)
    UIView.animate(withDuration: 0.60, delay: 0.0, usingSpringWithDamping: 0.3, initialSpringVelocity: 0.3, options: .curveEaseInOut, animations: { () -> Void in
        sender.transform = CGAffineTransform(rotationAngle: 0.0)
    }, completion: nil)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X