内容分为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放中间,设置约束就可以了