如何启用多点触摸并同时绘制两条直线?代码问题求助
解决iOS多点触摸同时绘制多条直线的问题
我来帮你搞定这个多点触摸绘图的问题~咱先看看问题出在哪:你现在的代码里只用了一个currentLine变量,而且每次触摸事件都只取touches.first!——这就意味着不管你同时用几个手指,程序永远只处理第一个摸上去的手指,自然没法同时画两条线啦。
要实现多点同时绘图,核心是给每个触摸点单独维护一条正在绘制的线,下面是具体的修改方案:
步骤1:修改数据结构
把单个的currentLine改成字典,用UITouch作为key(每个触摸事件有唯一的UITouch实例),对应的值是正在绘制的Line:
// 替换原来的var currentLine: Line? var currentLines = [UITouch: Line]()
步骤2:更新触摸事件处理方法
touchesBegan:处理所有新触摸点
遍历所有触摸事件,给每个触摸创建一条初始的线,存入字典:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { print(#function) for touch in touches { let location = touch.location(in: self) let newLine = Line(begin: location, end: location) currentLines[touch] = newLine } setNeedsDisplay() }
touchesMoved:更新每个触摸对应的线
遍历所有移动的触摸点,找到对应的线并更新终点:
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { print(#function) for touch in touches { guard let line = currentLines[touch] else { continue } let location = touch.location(in: self) line.end = location } setNeedsDisplay() }
touchesEnded:完成触摸对应的线
把结束的触摸对应的线移到finishedLines,并从字典移除:
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { print(#function) for touch in touches { guard let line = currentLines.removeValue(forKey: touch) else { continue } finishedLines.append(line) } setNeedsDisplay() }
touchesCancelled:取消触摸对应的线
直接从字典移除取消的触摸对应的线:
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) { print(#function) for touch in touches { currentLines.removeValue(forKey: touch) } setNeedsDisplay() }
步骤3:更新draw方法,绘制所有当前线
原来的draw方法只画一条currentLine,现在要遍历字典里的所有线来绘制:
override func draw(_ rect: CGRect) { // 绘制已完成的线 finishedLineColor.setStroke() for line in finishedLines { strokeLine(line: line) } // 调试用的固定线(可以保留或删除) strokeLine(line: line1) strokeLine(line: line2) // 绘制所有正在绘制的线 currentLineColor.setStroke() for line in currentLines.values { strokeLine(line: line) } }
额外注意点
- 确保你的
Line类是可以修改end属性的(比如用var end: CGPoint) - 再次确认Storyboard里你的
DrawView的Multiple Touch选项已经勾选(你说已经开了,但可以再检查下) - 如果你的
strokeLine方法里用了lineWidth,记得把原来的固定值改成你定义的lineThickness属性,保持样式统一:func strokeLine(line: Line){ let path = UIBezierPath(); path.lineWidth = lineThickness // 这里改成你的IBInspectable属性 path.lineCapStyle = CGLineCap.round; path.move(to: line.begin); path.addLine(to: line.end); path.stroke(); }
这样修改后,你就能同时用多个手指在屏幕上绘制多条独立的直线啦~
内容的提问来源于stack exchange,提问作者TopCoderChallenges
相关产品推荐
相关产品推荐

