CAShapeLayer 左上角缺少像素
CAShapeLayer missing pixel in top-left corner
我正在使用 CAShapeLayer
和 UIBezierPath
在视图中绘制带边框的框。
这工作正常,但第一个像素(顶部,左侧)未绘制。
这是我的代码:
let focusSize = CGRect(x: focusX, y: focusY, width: focusWidth, height: focusHeight)
let focusPath = UIBezierPath(roundedRect: focusSize, cornerRadius: 0)
let borderLayer = CAShapeLayer()
borderLayer.path = focusPath.cgPath
borderLayer.fillColor = UIColor.clear.cgColor
borderLayer.strokeColor = UIColor.white.cgColor
borderLayer.lineWidth = 2
borderLayer.frame = self.someView.bounds
self.someView.layer.addSublayer(borderLayer)
结果(注意左上角的像素):
我认为这可能与抗锯齿有关,但调整 x、y 和 borderWidth 似乎无法解决问题。
有谁知道是什么原因造成的?
出于某种原因,当您使用 (roundedRect rect: CGRect, cornerRadius: CGFloat)
创建路径时,它没有关闭(尽管它在文档中有说明)。
调用 focusPath.close()
关闭路径并删除丢失的像素。
但是,如果您不想要圆角,只需使用普通矩形即可正确绘制。
let focusPath = UIBezierPath(rect: focusSize)
任何对这里感兴趣的人都是结果路径:
UIBezierPath(roundedRect: CGRect(x: 10, y: 10, width: 100, height: 100), cornerRadius: 0)
<UIBezierPath: 0x6180000b8000; <MoveTo {10, 10}>,
<LineTo {110, 10}>,
<LineTo {110, 110}>,
<LineTo {10, 110}>,
<LineTo {10, 10}>,
<LineTo {10, 10}>
//After calling path.close()
<UIBezierPath: 0x6180000b8000; <MoveTo {10, 10}>,
<LineTo {110, 10}>,
<LineTo {110, 110}>,
<LineTo {10, 110}>,
<LineTo {10, 10}>,
<LineTo {10, 10}>,
<Close>
UIBezierPath(rect: CGRect(x: 10, y: 10, width: 100, height: 100))
<UIBezierPath: 0x6180000b7f40; <MoveTo {10, 10}>,
<LineTo {110, 10}>,
<LineTo {110, 110}>,
<LineTo {10, 110}>,
<Close>
设置 lineCap
可能会使框正确显示,但无法解决问题,因为它只是扩展了可见端点并掩盖了缺失的位。设置 borderLayer.lineJoin = kCALineJoinBevel
看看为什么这会成为问题。
您看到矩形上缺少像素的原因是您没有正确配置 lineCap
属性。
尝试添加这一行:
borderLayer.lineCap = kCALineCapSquare
有关行上限(和理解也很重要的行连接)的更多信息,请参阅此页面:http://calayer.com/core-animation/2016/05/22/cashapelayer-in-depth.html#line-cap
是的,根据文档,它应该是一个矩形,但我认为它没有提到 lineWidth
这似乎是您看到缺少像素的原因
borderLayer.lineWidth = 2
现在,当您将宽度更改为 1 时,它会绘制一个完美的矩形,不会丢失任何像素
将 lineWidth 更改为 10 显示间隙有相当大的差异
你的问题的解决方案就是使用这个
borderLayer.lineCap = kCALineCapSquare
勾选这些lineCap & Line Cap Values
我正在使用 CAShapeLayer
和 UIBezierPath
在视图中绘制带边框的框。
这工作正常,但第一个像素(顶部,左侧)未绘制。
这是我的代码:
let focusSize = CGRect(x: focusX, y: focusY, width: focusWidth, height: focusHeight)
let focusPath = UIBezierPath(roundedRect: focusSize, cornerRadius: 0)
let borderLayer = CAShapeLayer()
borderLayer.path = focusPath.cgPath
borderLayer.fillColor = UIColor.clear.cgColor
borderLayer.strokeColor = UIColor.white.cgColor
borderLayer.lineWidth = 2
borderLayer.frame = self.someView.bounds
self.someView.layer.addSublayer(borderLayer)
结果(注意左上角的像素):
我认为这可能与抗锯齿有关,但调整 x、y 和 borderWidth 似乎无法解决问题。 有谁知道是什么原因造成的?
出于某种原因,当您使用 (roundedRect rect: CGRect, cornerRadius: CGFloat)
创建路径时,它没有关闭(尽管它在文档中有说明)。
调用 focusPath.close()
关闭路径并删除丢失的像素。
但是,如果您不想要圆角,只需使用普通矩形即可正确绘制。
let focusPath = UIBezierPath(rect: focusSize)
任何对这里感兴趣的人都是结果路径:
UIBezierPath(roundedRect: CGRect(x: 10, y: 10, width: 100, height: 100), cornerRadius: 0)
<UIBezierPath: 0x6180000b8000; <MoveTo {10, 10}>,
<LineTo {110, 10}>,
<LineTo {110, 110}>,
<LineTo {10, 110}>,
<LineTo {10, 10}>,
<LineTo {10, 10}>
//After calling path.close()
<UIBezierPath: 0x6180000b8000; <MoveTo {10, 10}>,
<LineTo {110, 10}>,
<LineTo {110, 110}>,
<LineTo {10, 110}>,
<LineTo {10, 10}>,
<LineTo {10, 10}>,
<Close>
UIBezierPath(rect: CGRect(x: 10, y: 10, width: 100, height: 100))
<UIBezierPath: 0x6180000b7f40; <MoveTo {10, 10}>,
<LineTo {110, 10}>,
<LineTo {110, 110}>,
<LineTo {10, 110}>,
<Close>
设置 lineCap
可能会使框正确显示,但无法解决问题,因为它只是扩展了可见端点并掩盖了缺失的位。设置 borderLayer.lineJoin = kCALineJoinBevel
看看为什么这会成为问题。
您看到矩形上缺少像素的原因是您没有正确配置 lineCap
属性。
尝试添加这一行:
borderLayer.lineCap = kCALineCapSquare
有关行上限(和理解也很重要的行连接)的更多信息,请参阅此页面:http://calayer.com/core-animation/2016/05/22/cashapelayer-in-depth.html#line-cap
是的,根据文档,它应该是一个矩形,但我认为它没有提到 lineWidth
这似乎是您看到缺少像素的原因
borderLayer.lineWidth = 2
现在,当您将宽度更改为 1 时,它会绘制一个完美的矩形,不会丢失任何像素
将 lineWidth 更改为 10 显示间隙有相当大的差异
你的问题的解决方案就是使用这个
borderLayer.lineCap = kCALineCapSquare
勾选这些lineCap & Line Cap Values