Как сделать нативную анимацию «Импульсный эффект» на UIButton - iOS


89

Я хотел бы иметь какую-то импульсную анимацию (бесконечный цикл «масштабирование - масштабирование») на UIButton, чтобы он сразу привлекал внимание пользователей.

Я видел эту ссылку Как создать эффект импульса с помощью -webkit-animation - outward rings, но мне было интересно, есть ли способ сделать это только с использованием собственной структуры?

Ответы:


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

Swift

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

См. Статью «Анимация содержания слоя».


1
Спасибо за Ваш ответ! Я должен сказать, что немного застрял. Я совершенно не знаком с CALayer и не уверен, как связать его с моим UIButton. К тому же ваш код выглядит так, как будто он меняет непрозрачность, а не масштаб.
Johann

8
Ладно). «Импульсная анимация» - это термин, обычно применяемый к эффекту мерцания, как сказано в примере по этой ссылке. Сейчас перечитываю ваш вопрос и понимаю, чего вы хотите. Сначала у каждого вида есть собственный слой. Если в проект добавлен фреймворк QartzCore, просто введите его, myView.layerчтобы получить к нему доступ. Слои можно анимировать с помощью Core Animation. Для масштабного преобразования вы можете использовать этот подход: Поддержка ключевого пути для полей структуры
бериллий

7
Фантастика! Использование @ "transform.scale" вместо @ "opacity" работает как шарм. Большое спасибо!
Johann

2
Если у вас его еще нет, вам нужно добавить #import <QuartzCore/QuartzCore.h>, чтобы получить все определения для CALayers.
progrmr

УГХ! Не редактируйте ответы трехлетней давности, которые устарели, если вы не обновляете фактический ответ до правильной современной версии. Добавление пробелов не обновляет его. Тем более, чтобы не воскресить его через 3 года.
Fogmeister

31

Вот быстрый код для этого;)

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)

2
Что случилось со всеми полуколонами? ;)
Christian

@Christian точка с запятой устанавливает тип константы pulseAnimation. Его не обязательно использовать, но он имеет тенденцию повышать ясность кода, когда правая часть присваивания не делает очевидным, какой тип оно назначит.
Скотт Чоу

@ScottChow, я думаю, вы говорите о толстой кишке. Мой комментарий был шуткой по отношению к исходному ответу, поскольку в Swift нет необходимости в точках с запятой. Думаю, это было не так очевидно сейчас, когда ответ сильно отредактировали :)
Christian

не забудьте добавить fromValue
Кев Уотс,

9

В быстром коде отсутствует a fromValue, мне пришлось добавить его, чтобы он заработал.

pulseAnimation.fromValue = NSNumber(float: 0.0)

Также forKeyдолжен быть установлен, иначе removeAnimationне работает.

self.view.layer.addAnimation(pulseAnimation, forKey: "layerAnimation")

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)
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.