美文网首页swift相关
可拖动的进度条加值气泡

可拖动的进度条加值气泡

作者: mrkison | 来源:发表于2022-04-22 10:43 被阅读0次
效果图.gif

内容分为3部分,1、可以拖动的进度条;2、绘制气泡;3、气泡中间放个lebel
1、可以拖动的进度条
1.1、简单的,放2个layer,也可以绘制要计算麻烦些。

private lazy var progressLayer: CALayer = {
    let layer = CALayer()
    layer.backgroundColor = UIColor.cyan.cgColor
    return layer
}()
private lazy var progressBackLayer: CALayer = {
    let layer = CALayer()
    layer.backgroundColor = UIColor.darkGray.cgColor
    return layer
}()

1.2、加拖动手势和处理点击手势

private lazy var pan = UIPanGestureRecognizer(target: self, action: #selector(panGesture(pan:)))

open override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
      super.touchesBegan(touches, with: event)
      guard touches.count == 1 else { return }
        
      setProgress(touch: touches.first!)
        
 }

2、绘制气泡
我是单独用一个view来绘制气泡,
2.1、代码

    override func draw(_ rect: CGRect) {
        super.draw(rect)
        var curX = width * triangleHorRatio
        if triangleHorOffset > 0 {
            curX = curX + min(triangleHorOffset, width - curX)
        }else {
            curX = curX + max(triangleHorOffset, -curX)
        }
        
        let triangleLeftX = max(0, curX - triangleWidth / 2)
        let triangleRightX = min(curX + triangleWidth / 2, width)
        let triangleY = height * (1 - triangleVerRatio)
        
        let bubbleCorner: CGFloat = triangleY / 2
        var arc: CGFloat = 0
        
        color.set()
        // 从三角底部,顺时针方向绘制的
        let path = UIBezierPath()
        path.lineWidth = 1
        
        if triangleLeftX > bubbleCorner {
            path.move(to: CGPoint(x: curX, y: height))
            path.addLine(to: CGPoint(x: triangleLeftX, y: triangleY))
            path.addLine(to: CGPoint(x: bubbleCorner, y: triangleY))
        }else {
            let co = (bubbleCorner - triangleLeftX) / bubbleCorner
            arc = CGFloat.pi / 2 - acos(co)
        }
        
        path.addArc(withCenter: CGPoint(x: bubbleCorner, y: bubbleCorner), radius: bubbleCorner, startAngle: CGFloat.pi / 2 + arc, endAngle: CGFloat.pi * 3 / 2, clockwise: true)
        
        path.addLine(to: CGPoint(x: width - bubbleCorner, y: 0))
        
        let co = (bubbleCorner - (width - triangleRightX)) / bubbleCorner
        if triangleRightX < width - bubbleCorner {
            arc = 0
        }else {
            arc = CGFloat.pi / 2 - acos(co)
        }
        path.addArc(withCenter: CGPoint(x: width - bubbleCorner, y: bubbleCorner), radius: bubbleCorner, startAngle: -CGFloat.pi / 2, endAngle: CGFloat.pi / 2 - arc, clockwise: true)
        if triangleRightX < width - bubbleCorner {
            path.addLine(to: CGPoint(x: triangleRightX, y: triangleY))
            path.addLine(to: CGPoint(x: curX, y: height))
        }else {
            path.addLine(to: CGPoint(x: curX, y: height))
        }
        
        path.close()
        
        switch type {
        case .fill:
            path.fill()
        case .stroke:
            path.stroke()
        }
    }

2.2、需要重绘的条件

  /// 设置三角偏移
    var triangleHorOffset: CGFloat = 0 {
        willSet {
            if abs(newValue - triangleHorOffset) > 1 {
                setNeedsDisplay()
            }
        }
    }

override func layoutSubviews() {
        super.layoutSubviews()
        if abs(lastSize.width - size.width) > 5 || abs(lastSize.height - size.height) > 2 {
            lastSize = size
            setNeedsDisplay()
        }
    }

3、气泡中间放个lebel,这个就简单了,直接加个label放中间,设置约束就可以了

相关文章

网友评论

    本文标题:可拖动的进度条加值气泡

    本文链接:https://www.haomeiwen.com/subject/stfaertx.html