iOS-自己实现水纹按钮动画效果

目标

当单击按钮时,会以单击点为圆心形成水纹扩散效果。扩散形状为圆形,扩散颜色为粉红色。在扩散的过程中按钮的状态为不可点击。

分析

因为没有准备大量的水纹单帧图片,水纹的颜色可以自由设置。而UIView和Layer的所有基础动画类型中也没有类似的动画实现方法,那么只能使用Timer+Draw重绘动画或CADisplayLink+Draw重绘动画来实现。

实现过程

1.按钮类设计
获取点击坐标:先获取属于该按钮的事件,取到第一个UITouch对象后,调用UITouch.location(in: button)得到点击位置在按钮坐标系中的坐标。
水纹效果:点击后按钮不可点击,创建定时器每0.02秒调用函数,每次函数调用圆形绘制半径+5且触发重绘,50次后清空数据并将定时器置为无效,最后恢复按钮点击功能。

import UIKit

class MyButton: UIButton {
    
    var viewRadius : CGFloat = 0
    var countNum = 0
    var timer : Timer?
    var circleCenterX : CGFloat = 0
    var circleCenterY : CGFloat = 0
    var targetAnimColor = UIColor(red: 216/255.0, green: 114/255.0, blue: 213/255.0, alpha: 0.8)
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        self.backgroundColor = UIColor(red: 50/255.0, green: 185/255.0, blue: 170/255.0, alpha: 1.0)
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
    }
    
    func startButtonAnimation(_ msenderBt : UIButton, _ mevent : UIEvent) {
        self.isUserInteractionEnabled = false
        let button = msenderBt as UIView
        let touchSet = mevent.touches(for: button)! as NSSet
        let touchArray = touchSet.allObjects as [AnyObject]
        let touch1 = touchArray[0] as! UITouch
        let point1 = touch1.location(in: button)
        
        self.circleCenterX = point1.x
        self.circleCenterY = point1.y
        timer = Timer.scheduledTimer(timeInterval: 0.02, target: self, selector: #selector(timeaction), userInfo: nil, repeats: true)
        RunLoop.main.add(timer!, forMode: .common)
    }
    
    @objc func timeaction() {
        countNum += 1
        
        let dismissTime = DispatchTime.now()
        DispatchQueue.main.asyncAfter(deadline: dismissTime) {
            self.viewRadius += 5
            self.setNeedsDisplay()
        }
        if countNum > 50 {
            countNum = 0
            timer?.invalidate()
            DispatchQueue.main.asyncAfter(deadline: dismissTime) {
                self.viewRadius = 0
                self.setNeedsDisplay()
            }
            self.isUserInteractionEnabled = true
        }
    }
    
    override func draw(_ rect: CGRect) {
        let ctx = UIGraphicsGetCurrentContext()!
        let endangle = CGFloat(Float.pi * 2)
        ctx.addArc(center: CGPoint(x: circleCenterX, y: circleCenterY), radius: viewRadius, startAngle: 0, endAngle: endangle, clockwise: false)
        let stockColor = targetAnimColor
        stockColor.setStroke()
        stockColor.setFill()
        ctx.fillPath()
    }
    
}

2.按钮调用

let loginButton = MyButton(frame: CGRect(x: 20, y: 230, width: self.view.frame.width-20*2, height: 50))
        loginButton.setTitle("登陆", for: .normal)
        loginButton.addTarget(self, action: #selector(loginAction(_:_:)), for: .touchUpInside)
        self.view.addSubview(loginButton)
@objc func loginAction(_ sender : UIButton, _ event : UIEvent) {
        let bt = sender as! MyButton
        bt.startButtonAnimation(sender, event)
    }

效果图

水纹按钮效果图.gif

如果觉得我的文章对您有用,请点击喜欢。您的支持将鼓励我继续创作!大家有什么不懂或我哪里写错了都可以评论留言,我一定会回复的~

你可能感兴趣的:(iOS-自己实现水纹按钮动画效果)