我有下面的Swift 2代码,当用户触摸并在屏幕上移动手指时绘制曲线。当用户移动他们的手指以在屏幕上给出一条连续的曲线时,添加曲线的新部分。 (上图)
但是,我希望更改下面的代码,以便在添加行的每个新部分并将其绘制到屏幕时,删除前一部分和前面的部分,以便在屏幕上看到的所有部分都是新部分,没有其他的。 (下图)
需要在下面的代码部分中修改哪些内容才能实现此目的?
// Swift 2 code below tested using Xcode 7.0.1.
class drawLines: UIView {
let path=UIBezierPath()
var previousPoint:CGPoint = CGPoint.zero
var strokeColor:UIColor?
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func drawRect(rect: CGRect) {
strokeColor = UIColor.blackColor()
strokeColor?.setStroke()
path.lineWidth = 10
path.stroke()
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
let touch: AnyObject? = touches.first
let currentPoint = touch!.locationInView(self)
path.moveToPoint(currentPoint)
previousPoint=currentPoint
self.setNeedsDisplay()
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
let touch: AnyObject? = touches.first
let currentPoint = touch!.locationInView(self)
let midPoint = self.midPoint(previousPoint, p1: currentPoint)
path.addQuadCurveToPoint(midPoint,controlPoint: previousPoint)
previousPoint=currentPoint
self.setNeedsDisplay()
path.moveToPoint(midPoint)
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
self.setNeedsDisplay()
}
override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
self.touchesEnded(touches!, withEvent: event)
}
func midPoint(p0:CGPoint,p1:CGPoint)->CGPoint
{
let x=(p0.x+p1.x)/2
let y=(p0.y+p1.y)/2
return CGPoint(x: x, y: y)
}
}
答案 0 :(得分:3)
据我所知,没有办法从UIBezierPath
删除积分。您正在寻找的解决方案是将点存储在一个数组中,您可以自由地修改它,然后从该点数组创建路径。
<强>更新强>
我对你发布的评论重新阅读你的帖子感到有点困惑。话虽如此,我试图让下面的例子包含你需要的所有元素 - 如果我不理解你,你可能需要重新安排它们。
此代码从触摸开始点开始不断向数组添加点,包括移动时。我在最大点数上添加了一个上限,以便在需要时删除多余的线点。当用户松开手指时,我已经明确了所有要点。
注意:我试图让代码尽可能简单,以便清楚。一旦找到符合您需求的添加/删除点的正确组合,您应该考虑优化它。特别是,这假设了一种简单的绘图方法,其中所有绘图同时发生(与增量相比),这是无效的。删除多余点的方法也可以在您理解后进行优化。
import UIKit
class ViewController: UIViewController {
var points = [CGPoint]()
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
addTouch(touches.first)
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
addTouch(touches.first)
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
points.removeAll()
}
override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
points.removeAll()
}
func addTouch(touch: UITouch?) {
guard let touch = touch else { return }
let currentPoint = touch.locationInView(self.view)
points.append(currentPoint)
// if you want a limit on your line length, you need these lines
// 20 is an arbitrary number
while (points.count > 20) {
points.removeFirst()
}
}
}
剩下的就是你将它添加到当前的线条图代码中,你应该好好去。
Apple在图形性能方面做了很多关于WWDC的讨论。 This one in particular might be helpful.
答案 1 :(得分:1)
每次TwoStraws推荐时,您可以保存一系列点数并重建贝塞尔曲线路径。
另一种选择是使用CAShapeLayer绘制曲线,并更改shapeBegin属性。 (当你从shapeBegin = 1.0移动到shapeBegin = 0.0时,它会截断形状的开头。)
第三个选项是编辑删除先前点的路径。 Erica Sadun在她出色的iOS开发者的Cookbook系列中有示例代码,展示了如何解析Bezier路径中的点(如果我没记错的话,它实际上使用了Bezier路径中的底层CGPath对象。)这将比每次重建你的bezier路径,但更多的工作适合你。
答案 2 :(得分:0)
如果我理解你的问题,你会想要重置
touchesBegan()
方法中的路径
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
path.removeAllPoints()
// ...
}