扫描全能王 CS, Cam Scanner 很是强大,
本文简单仿一下他的选择区域功能。
端点可拖动
1, 识别点
本文例子比较简单,只有四个端点,用于拖拽
给定四个坐标,
先识别到开始点击的位置,距离哪个点近,
就认为要拖动那个点
// 四个点,按方位划分
enum SketchPointOption: Int{
case leftTop = 0, rightTop = 1, leftBottom = 2
case rightBottom = 3
}
// 先识别到开始点击的位置,距离哪个点,在一定范围内
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
guard let touch = touches.first else{
return
}
let currentPoint = touch.location(in: self)
// 判定选中的最大距离
let maxDistance: CGFloat = 20
let points = [defaultPoints.leftTop, defaultPoints.rightTop, defaultPoints.leftBottom,
defaultPoints.rightBottom]
for pt in points{
let distance = abs(pt.x - currentPoint.x) + abs(pt.y - currentPoint.y)
if distance <= maxDistance, let pointIndex = points.firstIndex(of: pt){
currentControlPointType = SketchPointOption(rawValue: pointIndex)
break
}
}
}
// 如果上一步识别到了,就更新选择点的位置,并重新连线
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesMoved(touches, with: event)
if currentControlPointType != nil, let touch = touches.first{
let current = touch.location(in: self)
guard bounds.contains(current) else{
return
}
// 就更新选择点的位置
prepare(point: current)
// 并重新连线
reloadData()
}
}
2,更新 UI
本文中,图上四个点,没有用四个控件,
四个点用的是 CALayer, 事件处理采用上面的触摸检测,
var lineLayer: CAShapeLayer = {
let l = CAShapeLayer()
l.lineWidth = 1
l.fillColor = UIColor.clear.cgColor
l.strokeColor = SketchColor.normal
return l
}()
var pointsLa