如何使按钮闪烁或闪烁?

Posted

技术标签:

【中文标题】如何使按钮闪烁或闪烁?【英文标题】:How to make a button flash or blink? 【发布时间】:2016-01-07 22:13:48 【问题描述】:

我正在尝试将按钮的颜色(只是闪烁/闪烁)在扫描正确时更改为绿色,在出现问题时更改为红色。我可以用这样的视图来做到这一点

func flashBG()
    UIView.animateWithDuration(0.7, animations: 
        self.view.backgroundColor = UIColor.greenColor()

    )

但是有一个按钮它会保持绿色

func flashBtn()
    UIButton.animateWithDuration(0.5, animations: 
        self.buttonScan.backgroundColor = UIColor.greenColor()
    )

我已经通过代码创建了按钮

func setupScanButton() 
    let X_Co = (self.view.frame.size.width - 100)/2
    let Y_Co = (self.viewForLayer.frame.size.height + 36/2)

    buttonScan.frame = CGRectMake(X_Co,Y_Co,100,100)
    buttonScan.layer.borderColor = UIColor.whiteColor().CGColor
    buttonScan.layer.borderWidth = 2
    buttonScan.layer.cornerRadius = 50
    buttonScan.setTitle("Scan", forState: .Normal)
    buttonScan.backgroundColor = UIColor.blueColor()
    buttonScan.addTarget(self, action: "buttonScanAction", forControlEvents: .TouchUpInside)
    buttonScan.setTitleColor(UIColor(red:255/255, green: 255/255, blue:255/255, alpha: 1), forState: UIControlState.Normal)

    self.view.addSubview(buttonScan)

我应该再次调用 setupScanButton() 吗?

【问题讨论】:

【参考方案1】:

这应该适用于 Swift 4

extension UIView
     func blink() 
         self.alpha = 0.2
         UIView.animate(withDuration: 1, delay: 0.0, options: [.curveLinear, .repeat, .autoreverse], animations: self.alpha = 1.0, completion: nil)
     

【讨论】:

这个答案很好用!这就是我直接在按钮上使用它的方式(无需扩展): myButton.alpha = 0.2 UIView.animate(withDuration: 1, delay: 0.0, options: [.curveLinear, .repeat, .autoreverse], 动画:myButton.alpha = 1.0,完成:无) @LanceSamaria 很高兴能帮到你:)【参考方案2】:

这将启动和停止闪烁按钮onClick,如果您只想立即闪烁按钮,只需使用第一条语句。

var flashing = false

@IBAction func btnFlash_Clicked(sender: AnyObject) 
        if !flashing
            self.buttonScan.alpha = 1.0
            UIView.animateWithDuration(0.5, delay: 0.0, options: [.CurveEaseInOut, .Repeat, .Autoreverse, .AllowUserInteraction], animations: () -> Void in
                self.buttonScan.alpha = 0.0
                , completion: (finished: Bool) -> Void in
            )

            flashing = true
        
    else
        UIView.animateWithDuration(0.1, delay: 0.0, options: [.CurveEaseInOut, .BeginFromCurrentState], animations: () -> Void in
            self.buttonScan.alpha = 1.0
            , completion: (finished: Bool) -> Void in
        )
    

Swift 5.x 版本

extension 的更新版本。

extension UIView 
    func blink(duration: TimeInterval = 0.5, delay: TimeInterval = 0.0, alpha: CGFloat = 0.0) 
        UIView.animate(withDuration: duration, delay: delay, options: [.curveEaseInOut, .repeat, .autoreverse], animations: 
            self.alpha = alpha
        )
    

调用函数:

button.blink() // without parameters
button.blink(duration: 1, delay: 0.1, alpha: 0.2) // with parameters

【讨论】:

我无法让用户交互使用 0.0 的 alpha。 See this answer for details. @Rashwan L,如何将其修改为 flash,只说 5 次? @theAlse,声明一个变量,如:var counter = 0,然后在 func btnFlash_Clicked 内部创建一个 if 语句,如 if counter > 4 return btnFlash_Clicked 的底部,只需将计数器值增加 1。 @RashwanL 感谢您的回复,我已经尝试过了,但没有成功,有一些我无法理解的可疑情况,计数器只增加一次,并且闪烁永远不会结束。 @theAlse, here 是我为您创建的示例项目,其中按钮闪烁五次。下载该项目,您将看到如何做到这一点。【参考方案3】:

希望能解决你的问题。

buttonScan.alpha = 1.0
UIView.animate(withDuration: 1.0, delay: 1.0, options: UIView.AnimationOptions.curveEaseOut, animations: 

    buttonScan.alpha = 0.0

, completion: nil) 

【讨论】:

@DaniSpringer 您使用的是哪个 swift 版本? 4.2 我很确定 在动画时按钮响应是否触摸?【参考方案4】:

斯威夫特 4

我用一些有用的选项做了一个扩展:

extension UIButton 
    open override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? 
        return self.bounds.contains(point) ? self : nil
    
    func blink(enabled: Bool = true, duration: CFTimeInterval = 1.0, stopAfter: CFTimeInterval = 0.0 ) 
        enabled ? (UIView.animate(withDuration: duration, //Time duration you want,
            delay: 0.0,
            options: [.curveEaseInOut, .autoreverse, .repeat],
            animations:  [weak self] in self?.alpha = 0.0 ,
            completion:  [weak self] _ in self?.alpha = 1.0 )) : self.layer.removeAllAnimations()
        if !stopAfter.isEqual(to: 0.0) && enabled 
            DispatchQueue.main.asyncAfter(deadline: .now() + stopAfter)  [weak self] in
                self?.layer.removeAllAnimations()
            
        
    

首先,当按钮的alpha 等于 0.0(透明)在动画期间。

然后,所有输入变量都有一个默认值,这样您就可以启动不带参数的blink() 方法

我还引入了enabled 参数来启动或停止按钮上的动画。

最后,如果你想你可以在特定时间后停止动画使用stopAfter参数。

用法:

yourButton.blink() // infinite blink effect with the default duration of 1 second

yourButton.blink(enabled:false) // stop the animation

yourButton.blink(duration: 2.0) // slowly the animation to 2 seconds

yourButton.blink(stopAfter:5.0) // the animation stops after 5 seconds.

典型用途:

yourButton.blink(duration: 1.5, stopAfter:10.0)
// your code..
yourButton.blink()
// other code..
yourButton.blink(enabled:false)

【讨论】:

【参考方案5】:

你可以试试这样的:

extension UIView 
    func blink() 
        UIView.animateWithDuration(0.5, //Time duration you want,
            delay: 0.0,
            options: [.CurveEaseInOut, .Autoreverse, .Repeat],
            animations:  [weak self] in self?.alpha = 0.0 ,
            completion:  [weak self] _ in self?.alpha = 1.0 )
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW,Int64(2 * NSEC_PER_SEC)),dispatch_get_main_queue())
            [weak self] in
            self?.layer.removeAllAnimations()
        
    

【讨论】:

我刚刚删除了视图。 在 swift 3+ 中,我这样做: DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) loadingView.removeFromSuperview() 【参考方案6】:
//MARK : Usage 

yourButton.flash()

extension UIButton 

    func flash() 

        let flash = CABasicAnimation(keyPath: "opacity")
        flash.duration = 0.5
        flash.fromValue = 1
        flash.toValue = 0.1
        flash.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
        flash.autoreverses = true
        flash.repeatCount = 3

        layer.add(flash, forKey: nil)
    

【讨论】:

【参考方案7】:

Swift 3.0

func btnFlash_Clicked(sender: AnyObject) 

    if !flashing
        callButton.alpha = 1.0
        UIView.animate(withDuration: 0.5, delay: 0.0, options: [.allowUserInteraction], animations: () -> Void in
            callButton.alpha = 0.5
        , completion: (finished: Bool) -> Void in
        )

        flashing = true
    
    else
        flashing = false
        callButton.alpha = 0.5
        UIView.animate(withDuration: 0.5, delay: 0.0, options: [.allowUserInteraction], animations: () -> Void in
            callButton.alpha = 1.0
        , completion: (finished: Bool) -> Void in
        )
    

【讨论】:

【参考方案8】:

Swift 3.0

func animateFlash()         
    flashView.alpha = 0
    flashView.isHidden = false
    UIView.animate(withDuration: 0.3, animations:  flashView.alpha = 1.0 )  finished in flashView.isHidden = true 

【讨论】:

【参考方案9】:

UIView 扩展“闪烁”视图并更改背景颜色:

/**
 Blinks a view with a given duration and optional color.

 - Parameter duration: The duration of the blink.
 - Parameter color: The color of the blink.
 */
public func blink(withDuration duration: Double = 0.25, color: UIColor? = nil) 

    alpha = 0.2
    UIView.animate(withDuration: duration, delay: 0.0, options: [.curveEaseInOut], animations: 
        self.alpha = 1.0
    )

    guard let newBackgroundColor = color else  return 
    let oldBackgroundColor = backgroundColor

    UIView.animate(withDuration: duration, delay: 0.0, options: [.curveEaseInOut], animations: 
        self.backgroundColor = newBackgroundColor
        self.backgroundColor = oldBackgroundColor
    )


然后你会使用如下:

buttonScan.blink(color: .green)

【讨论】:

【参考方案10】:
myButton.alpha = 0.7

UIView.animate(withDuration: 0.3,
                      delay: 1.0,
                    options: [UIView.AnimationOptions.curveLinear, UIView.AnimationOptions.repeat, UIView.AnimationOptions.autoreverse],
                 animations:  myButton.alpha = 1.0 ,
                 completion: nil)

【讨论】:

@JobinsJohn 试试 myView.layer.removeAllAnimations() 我刚刚尝试了您的建议,但我无法正确执行。我的基本想法是让应用程序运行 2 或 3 秒,然后停止。【参考方案11】:

使用 UIViewPropertyAnimatorSwift 5

UIViewPropertyAnimator.runningPropertyAnimator(withDuration: 1, delay: 0, options: [.curveLinear,.repeat], animations: 
       UIView.setAnimationRepeatCount(3000)
       self.buttonScan.alpha = 0.0
 , completion: _ in   )

【讨论】:

【参考方案12】:

另一个流畅的 Swift 5 动画版本:

 public extension UIView 
  func blink(duration: TimeInterval) 
    let initialAlpha: CGFloat = 1
    let finalAlpha: CGFloat = 0.2
    
    alpha = initialAlpha
    
    UIView.animateKeyframes(withDuration: duration, delay: 0, options: .beginFromCurrentState) 
      UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.5) 
        self.alpha = finalAlpha
      
      
      UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.5) 
        self.alpha = initialAlpha
      
    
  

【讨论】:

以上是关于如何使按钮闪烁或闪烁?的主要内容,如果未能解决你的问题,请参考以下文章

按下按钮时快速闪烁或闪烁 2 种随机颜色

请教大家如何使VIM的光标不闪烁?

如何使用 jQuery 使 <li> 元素闪烁/闪烁不同的颜色

按钮的背景在鼠标悬停时闪烁或消失

按钮长按控制闪烁循环

iPad Safari:点击链接时如何禁用快速闪烁效果