【问题标题】: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() 吗?

【问题讨论】:

    标签: ios swift uibutton


    【解决方案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
                      }
                    }
                  }
                }
                

                【讨论】:

                  猜你喜欢
                  • 2018-01-30
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-05-15
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多