ProgressButton.swift 5.08 KB
//
//  ProgressButton.swift
//  Twear
//
//  Created by yangbin on 2021/12/29.
//

import Foundation
import UIKit

fileprivate let StartAngle = CGFloat(Double.pi / 2)

//protocol ProgressButtonDelegate: NSObjectProtocol {
//    func progressFinished()
//}

public class ProgressButton: UIButton {
    // 延迟初始化背景层,采用 fill 来绘层背景
    private lazy var bgLayer: CAShapeLayer = CAShapeLayer()
    // 延迟初始化进度条层,采用 stroke 来绘制边框
    private lazy var progressLayer: CAShapeLayer = CAShapeLayer()
    // 进度条百分比(最小为 0.0,最大为 1.0)
    private var progress: Double = 0
    
    private let percent: CGFloat = 1.0/20.0
    // 延迟初始化标签文本内容
//    private lazy var label: UILabel = UILabel(frame: CGRect.zero)
    var progressClosure: (() -> ())?
    public override init(frame: CGRect) {
        super.init(frame: frame)
        initView()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        initView()
    }
    
    // 仅初始化 layer & label,以及颜色,后续再给定实际大小和约束
    func initView() {
        // fillColor   用于背景颜色填充
        // strokeColor 用于线条颜色

        self.addTarget(self, action: #selector(touchDown(_:)), for: .touchDown)
        self.addTarget(self, action: #selector(touchCancel(_:)), for: [.touchDragExit, .touchDragOutside, .touchUpInside])
//        self.addTarget(self, action: #selector(touchFinish(_:)), for: .touchUpInside)
        // 0.25 透明度的白色背景
        bgLayer.fillColor = UIColor(red: 1, green: 1, blue: 1, alpha: 0).cgColor
        layer.addSublayer(bgLayer)
        
        // 边框全白,边框宽度为 4
        progressLayer = CAShapeLayer()
        progressLayer.fillColor = nil
        progressLayer.strokeColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1).cgColor
        progressLayer.lineWidth = 4.0
        layer.addSublayer(progressLayer)
        
        // 标签字体颜色为纯白
//        label.textColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1)
//        // 使用约束来布局
//        label.translatesAutoresizingMaskIntoConstraints = false
//        addSubview(label)
    }
    
    public override func draw(_ rect: CGRect) {
        super.draw(rect)
       
        
    }
    
    @objc func touchDown(_ sender: UIButton) {
        progressLayer.strokeEnd = 0
        GCDTimer.shared.scheduledDispatchTimer(WithTimerName: "ProgressButton", timeInterval: 0.1, queue: .main, repeats: true) { [weak self] in
            self?.startTimer()
        }
    }
    @objc func touchCancel(_ sender: Any) {
        progressLayer.strokeEnd = 0
        cancelTimer()
    }
    
    private func cancelTimer() {
        if GCDTimer.shared.isExistTimer(WithTimerName: "ProgressButton") {
            GCDTimer.shared.cancleTimer(WithTimerName: "ProgressButton")
        }
    }
    
    func startTimer() {
        if progressLayer.strokeEnd >= 1 {
            cancelTimer()
            progressLayer.removeFromSuperlayer()
            progressClosure?()
        } else {
            progressLayer.strokeEnd += percent
        }
    }
    
    // 布局 resize 时会触发该方法
    public override func layoutSubviews() {
        super.layoutSubviews()
        let radius = bounds.height / 2 - 2
        bgLayer.path = UIBezierPath(roundedRect: bounds, cornerRadius: radius).cgPath

        // 设置 start 从 12点钟方向开始(默认是3点钟方向)
        // end = 360度 * progress - start
        // 设置为 顺时针 方向
        let end = CGFloat(Double.pi * 2) - StartAngle
        progressLayer.path = UIBezierPath(arcCenter: CGPoint(rect: bounds), radius: radius,
                                          startAngle: -StartAngle, endAngle: end,
                                          clockwise: true).cgPath
        progressLayer.strokeEnd = 0
        // 因为 宽 = 高,所以,圆角为宽 or 高的一半即可
        
        // 设置 label 的中心点 = self 的中心点
//        NSLayoutConstraint.activate([
//            label.centerXAnchor.constraint(equalTo: self.centerXAnchor),
//            label.centerYAnchor.constraint(equalTo: self.centerYAnchor)
//        ])
    }
    deinit {
        print("deinit\(NSStringFromClass(type(of: self)))!!!!!!!")
    }
    
    public func setProgress(_ progress: Double) {
        // 进度条目标值,即 0.0 -> progress
//        self.progress = progress
        // 初始化 label
//        label.text = "\(duration)s"
        progressLayer.strokeEnd = 0.5
        // 创建进度条动画,时长 = duration
//        if !animated {
//            let animation = CABasicAnimation(keyPath: "strokeEnd")
//            animation.duration = 1
//            animation.fromValue = 0
//            animation.toValue = 1
//            progressLayer.add(animation, forKey: nil)
//        }
    }
    
//    public func setContent(_ text: String) {
//        label.text = "\(text)s"
//    }
}

extension CGPoint {
    // 扩展,取 rect 的中心点
    init(rect: CGRect) {
        self.init(x: rect.width / 2, y: rect.height / 2)
    }
}