更改 CALayer 的大小也会更改先前添加的图层大小的大小
我正在尝试使用此自定义类绘制 UIImageView,并且我希望能够更改用户绘制的线条的大小和颜色。但每次我更改 CALayer 的大小或颜色时,先前添加的图层的颜色和大小也会随之改变。
class DrawingImageView: UIImageView {
private lazy var path = UIBezierPath()
private lazy var previousTouchPoint = CGPoint.zero
var strokeColor: CGColor!
var strokeWidth: CGFloat!
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
let shapeLayer = CAShapeLayer()
shapeLayer.lineWidth = strokeWidth ?? 4
shapeLayer.strokeColor = strokeColor ?? UIColor.black.cgColor
shapeLayer.lineCap = .round
shapeLayer.lineJoin = .round
layer.addSublayer(shapeLayer)
if let location = touches.first?.location(in: self) { previousTouchPoint = location }
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesMoved(touches, with: event)
if let location = touches.first?.location(in: self) {
path.move(to: location)
path.addLine(to: previousTouchPoint)
previousTouchPoint = location
let layerA = layer.sublayers?.last as! CAShapeLayer
layerA.path = path.cgPath
}
}
}
这就是我将该类分配给 tempImageView 的方式
let mainImageView = UIImageView()
var tempImgView: DrawingImageView?
mainImageView.frame = CGRect(x: 0, y: self.view.bounds.height / 7, width: imageWidth, height: imageHieght)
mainImageView.contentMode = .scaleAspectFit
mainImageView.layer.zPosition = 2
mainImageView.isOpaque = false
mainImageView.backgroundColor = .clear
mainImageView.isUserInteractionEnabled = true
mainImageView.tintColor = .clear
self.view.addSubview(mainImageView)
func DrawOverImage() {
mainImageView.isHidden = true
let drawnImageView = DrawingImageView(frame: mainImageView.frame)
drawnImageView.image = mainImageView.image
drawnImageView.contentMode = .scaleAspectFit
drawnImageView.isUserInteractionEnabled = true
drawnImageView.layer.zPosition = 3
self.tempImgView?.isUserInteractionEnabled = true
self.tempImgView = drawnImageView
self.view.addSubview(tempImgView!)
}
我还尝试创建 CAShapeLayers 数组并将图层添加到数组中,然后分配替换子图层,如 View.layer.subLayers[0] =layers[0] 但这也不起作用,我在网上找不到任何有用的资源。
任何帮助或建议将不胜感激,谢谢。
i'm trying to draw over UIImageView with this custome class and i would like to be able to change the size and color of lines being drawn by user. But every time i change the size or color of CALayer Previously added layer's color and size also changes then.
class DrawingImageView: UIImageView {
private lazy var path = UIBezierPath()
private lazy var previousTouchPoint = CGPoint.zero
var strokeColor: CGColor!
var strokeWidth: CGFloat!
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
let shapeLayer = CAShapeLayer()
shapeLayer.lineWidth = strokeWidth ?? 4
shapeLayer.strokeColor = strokeColor ?? UIColor.black.cgColor
shapeLayer.lineCap = .round
shapeLayer.lineJoin = .round
layer.addSublayer(shapeLayer)
if let location = touches.first?.location(in: self) { previousTouchPoint = location }
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesMoved(touches, with: event)
if let location = touches.first?.location(in: self) {
path.move(to: location)
path.addLine(to: previousTouchPoint)
previousTouchPoint = location
let layerA = layer.sublayers?.last as! CAShapeLayer
layerA.path = path.cgPath
}
}
}
this is how i assign that class to tempImageView
let mainImageView = UIImageView()
var tempImgView: DrawingImageView?
mainImageView.frame = CGRect(x: 0, y: self.view.bounds.height / 7, width: imageWidth, height: imageHieght)
mainImageView.contentMode = .scaleAspectFit
mainImageView.layer.zPosition = 2
mainImageView.isOpaque = false
mainImageView.backgroundColor = .clear
mainImageView.isUserInteractionEnabled = true
mainImageView.tintColor = .clear
self.view.addSubview(mainImageView)
func DrawOverImage() {
mainImageView.isHidden = true
let drawnImageView = DrawingImageView(frame: mainImageView.frame)
drawnImageView.image = mainImageView.image
drawnImageView.contentMode = .scaleAspectFit
drawnImageView.isUserInteractionEnabled = true
drawnImageView.layer.zPosition = 3
self.tempImgView?.isUserInteractionEnabled = true
self.tempImgView = drawnImageView
self.view.addSubview(tempImgView!)
}
i also tried creating array of CAShapeLayers and add layers to an array and then assign replace subLayer like View.layer.subLayers[0] = layers[0] but that also didn't work and i couldn't find any useful resource online.
any help or suggestion would be really appreciated, thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是因为您每次都继续相同的路径,因此最新的描边颜色和宽度会应用于整个路径。
在不考虑太多其他逻辑的情况下,我相信您应该每次在
touchesBegan
中初始化一个新路径,并且这个新路径应该在touchesMoved
中使用,所以在
touchesBegan
,尝试在layer.addSublayer(shapeLayer)
之后添加path = UIBezierPath()
,看看这是否能满足您的需求That is because you are continuing the same path each time and so the latest stroke color and width gets applied to the whole path.
Without looking at much of your other logic, I believe you should initialize a new path each time in your
touchesBegan
and this new path should be used intouchesMoved
So in
touchesBegan
, try addingpath = UIBezierPath()
afterlayer.addSublayer(shapeLayer)
and see if this gives you what you are looking for