UIBezierPath 线在绘制另一条时消失
UIBezierPath line disappears when drawing another one
我正在尝试使用 UIbezierPath 绘制多个,但每当我尝试绘制第二个时,第一个就会消失。试图创建多个 BezierPath 并将它们放入一个数组但是当它 运行 进入 case:ended
时我得到了这个错误
test[2687:238999] [Unknown process name] CGPathCloseSubpath: no current point.
这是我的代码
private lazy var lineShape: CAShapeLayer = {
let lineShape = CAShapeLayer()
lineShape.strokeColor = UIColor.blue.cgColor
lineShape.lineWidth = 2.0
return lineShape
}()
var bezierPathArr:NSMutableArray = []
private var panGestureStartPoint: CGPoint = .zero
private lazy var panRecognizer: UIPanGestureRecognizer = {
return UIPanGestureRecognizer(target: self, action: #selector(panGestureCalled(_:)))
}()
@objc func panGestureCalled(_: UIPanGestureRecognizer) {
let linePath = UIBezierPath()
let currentPanPoint = panRecognizer.location(in: self.view)
switch panRecognizer.state {
case .began:
panGestureStartPoint = currentPanPoint
self.view.layer.addSublayer(lineShape)
bezierPathArr.add(linePath)
case .changed:
linePath.move(to: panGestureStartPoint)
linePath.addLine(to: currentPanPoint)
lineShape.path = linePath.cgPath
case .ended:
let finalPath:UIBezierPath = bezierPathArr.lastObject as! UIBezierPath
finalPath.close()
default: break
}
}
由于 lazy
创建了您的 CAShapeLayer
,无论何时向视图添加层,您都在使用相同的对象引用。连同在该参考上设置路径将为您提供您正在经历的行为。
为了实现预期的行为,您需要为每个完成的手势创建并存储一个新的 CAShapeLayer
。这是一个工作示例:
class ViewController: UIViewController {
private lazy var panRecognizer: UIPanGestureRecognizer = {
return UIPanGestureRecognizer(target: self, action: #selector(panGestureCalled(_:)))
}()
/// The path that is being drawn (resets on .began, closes on .ended)
private var currentPath: UIBezierPath = .init()
/// All of the layers added to the view
private var shapes: [CAShapeLayer] = []
override func viewDidLoad() {
super.viewDidLoad()
view.addGestureRecognizer(panRecognizer)
}
@objc private func panGestureCalled(_ sender: UIPanGestureRecognizer) {
let point = sender.location(in: self.view)
switch sender.state {
case .began:
// Reset the path
currentPath = .init()
// Set the starting point
currentPath.move(to: point)
// Creates a new layer when gesture starts.
let layer = newShapeLayer()
// Save the layer with all shapes.
shapes.append(layer)
// Add the layer to the view
view.layer.addSublayer(layer)
case .changed:
// Update the current path to the new point
currentPath.addLine(to: point)
case .ended:
// Close/Finish the path
currentPath.close()
default:
break
}
// Update the most-current shape with the path being drawn.
shapes.last?.path = currentPath.cgPath
}
/// Creates a new `CAShapeLayer`
private func newShapeLayer() -> CAShapeLayer {
let layer = CAShapeLayer()
layer.frame = view.bounds
layer.strokeColor = UIColor.blue.cgColor
layer.lineWidth = 2.0
return layer
}
}
我正在尝试使用 UIbezierPath 绘制多个,但每当我尝试绘制第二个时,第一个就会消失。试图创建多个 BezierPath 并将它们放入一个数组但是当它 运行 进入 case:ended
test[2687:238999] [Unknown process name] CGPathCloseSubpath: no current point.
这是我的代码
private lazy var lineShape: CAShapeLayer = {
let lineShape = CAShapeLayer()
lineShape.strokeColor = UIColor.blue.cgColor
lineShape.lineWidth = 2.0
return lineShape
}()
var bezierPathArr:NSMutableArray = []
private var panGestureStartPoint: CGPoint = .zero
private lazy var panRecognizer: UIPanGestureRecognizer = {
return UIPanGestureRecognizer(target: self, action: #selector(panGestureCalled(_:)))
}()
@objc func panGestureCalled(_: UIPanGestureRecognizer) {
let linePath = UIBezierPath()
let currentPanPoint = panRecognizer.location(in: self.view)
switch panRecognizer.state {
case .began:
panGestureStartPoint = currentPanPoint
self.view.layer.addSublayer(lineShape)
bezierPathArr.add(linePath)
case .changed:
linePath.move(to: panGestureStartPoint)
linePath.addLine(to: currentPanPoint)
lineShape.path = linePath.cgPath
case .ended:
let finalPath:UIBezierPath = bezierPathArr.lastObject as! UIBezierPath
finalPath.close()
default: break
}
}
由于 lazy
创建了您的 CAShapeLayer
,无论何时向视图添加层,您都在使用相同的对象引用。连同在该参考上设置路径将为您提供您正在经历的行为。
为了实现预期的行为,您需要为每个完成的手势创建并存储一个新的 CAShapeLayer
。这是一个工作示例:
class ViewController: UIViewController {
private lazy var panRecognizer: UIPanGestureRecognizer = {
return UIPanGestureRecognizer(target: self, action: #selector(panGestureCalled(_:)))
}()
/// The path that is being drawn (resets on .began, closes on .ended)
private var currentPath: UIBezierPath = .init()
/// All of the layers added to the view
private var shapes: [CAShapeLayer] = []
override func viewDidLoad() {
super.viewDidLoad()
view.addGestureRecognizer(panRecognizer)
}
@objc private func panGestureCalled(_ sender: UIPanGestureRecognizer) {
let point = sender.location(in: self.view)
switch sender.state {
case .began:
// Reset the path
currentPath = .init()
// Set the starting point
currentPath.move(to: point)
// Creates a new layer when gesture starts.
let layer = newShapeLayer()
// Save the layer with all shapes.
shapes.append(layer)
// Add the layer to the view
view.layer.addSublayer(layer)
case .changed:
// Update the current path to the new point
currentPath.addLine(to: point)
case .ended:
// Close/Finish the path
currentPath.close()
default:
break
}
// Update the most-current shape with the path being drawn.
shapes.last?.path = currentPath.cgPath
}
/// Creates a new `CAShapeLayer`
private func newShapeLayer() -> CAShapeLayer {
let layer = CAShapeLayer()
layer.frame = view.bounds
layer.strokeColor = UIColor.blue.cgColor
layer.lineWidth = 2.0
return layer
}
}