Jak zrobić natywną animację „efektu pulsu” na UIButton - iOS

Odpowiedzi:

199
CABasicAnimation *theAnimation;

theAnimation=[CABasicAnimation animationWithKeyPath:@"opacity"];
theAnimation.duration=1.0;
theAnimation.repeatCount=HUGE_VALF;
theAnimation.autoreverses=YES;
theAnimation.fromValue=[NSNumber numberWithFloat:1.0];
theAnimation.toValue=[NSNumber numberWithFloat:0.0];
[theLayer addAnimation:theAnimation forKey:@"animateOpacity"]; //myButton.layer instead of

Szybki

let pulseAnimation = CABasicAnimation(keyPath: #keyPath(CALayer.opacity))
pulseAnimation.duration = 1
pulseAnimation.fromValue = 0
pulseAnimation.toValue = 1
pulseAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
pulseAnimation.autoreverses = true
pulseAnimation.repeatCount = .greatestFiniteMagnitude
view.layer.add(pulseAnimation, forKey: "animateOpacity")

Zobacz artykuł „Animowanie zawartości warstwy”

beryl
źródło
1
Dzięki za odpowiedź! Muszę powiedzieć, że trochę utknąłem. W ogóle nie znam CALayera i nie jestem pewien, jak połączyć go z moim UIButtonem. Dodatkowo twój kod wygląda tak, jakby zmieniał krycie, a nie skalowanie.
Johann
8
w porządku). „Animacja pulsu” to termin zwykle stosowany w odniesieniu do efektu migotania - jak wspomniano w przykładzie w tym linku. Teraz ponownie przeczytałem Twoje pytanie i rozumiem, czego chcesz. Na początku każdy widok ma własną warstwę. Jeśli framework QartzCore jest dodany do projektu, po prostu wpisz, myView.layeraby uzyskać do niego dostęp. Możesz animować warstwy za pomocą Core Animation. Do transformacji skali możesz użyć tego podejścia: Key Path Support for Structure Fields
beryllium.
7
Fantastyczny! Używanie @ "transform.scale" zamiast @ "opacity" działa jak urok. Wielkie dzięki!
Johann
2
Jeśli jeszcze go nie masz, musisz go dodać #import <QuartzCore/QuartzCore.h>, aby uzyskać wszystkie definicje CALayers.
progrmr
UGH! Nie edytuj odpowiedzi sprzed 3 lat, które są nieaktualne, chyba że aktualizujesz właściwą odpowiedź do poprawnej, nowoczesnej wersji. Dodawanie spacji nie jest aktualizacją. Zwłaszcza żeby nie wskrzeszać go po 3 latach.
Fogmeister
31

Oto szybki kod;)

let pulseAnimation:CABasicAnimation = CABasicAnimation(keyPath: "transform.scale")
pulseAnimation.duration = 1.0
pulseAnimation.toValue = NSNumber(value: 1.0)
pulseAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
pulseAnimation.autoreverses = true
pulseAnimation.repeatCount = .greatestFiniteMagnitude
self.view.layer.add(pulseAnimation, forKey: nil)
Ravi Sharma
źródło
2
O co chodzi z tymi wszystkimi średnikami? ;)
Christian
@Christian średnik określa typ stałej pulsacji animacji. Nie jest to konieczne, ale ma tendencję do zwiększania przejrzystości kodu, gdy po prawej stronie przypisania nie jest oczywiste, jaki typ zostanie przypisany.
Scott Chow,
@ScottChow chyba mówisz o okrężnicy. Mój komentarz był żartem do oryginalnej odpowiedzi, ponieważ w Swift nie ma potrzeby używania średników. Chyba nie było to takie oczywiste teraz, kiedy odpowiedź była często edytowana :)
Christian
upewnij się, że dodałeś fromValue
Kev Wats
9

W szybkim kodzie brakuje a fromValue, musiałem go dodać, aby działał.

pulseAnimation.fromValue = NSNumber(float: 0.0)

Również forKeypowinien być ustawiony, w przeciwnym razie removeAnimationnie działa.

self.view.layer.addAnimation(pulseAnimation, forKey: "layerAnimation")
Bassebus
źródło
3
func animationScaleEffect(view:UIView,animationTime:Float)
{
    UIView.animateWithDuration(NSTimeInterval(animationTime), animations: {

        view.transform = CGAffineTransformMakeScale(0.6, 0.6)

        },completion:{completion in
            UIView.animateWithDuration(NSTimeInterval(animationTime), animations: { () -> Void in

                view.transform = CGAffineTransformMakeScale(1, 1)
            })
    })

}


@IBOutlet weak var perform: UIButton!

@IBAction func prefo(sender: AnyObject) {
    self.animationScaleEffect(perform, animationTime: 0.7)
}
Ahmad ELkhwaga
źródło