[英]CAShapeLayer missing pixel in top-left corner
I'm using a CAShapeLayer
with a UIBezierPath
to draw a bordered box in a view. 我正在使用带有
CAShapeLayer
的UIBezierPath
在视图中绘制带边框的框。
This is working fine, but the very first pixel (top, left) is not drawn. 这工作正常,但没有绘制第一个像素(顶部,左侧)。
This is my code: 这是我的代码:
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)
The result (note the pixel in the top, left corner): 结果(注意顶部左上角的像素):
I thought this might be related to antialiasing, but playing around with the x, y and borderWidth does not seem to fix the issue. 我认为这可能与抗锯齿相关,但是使用x,y和borderWidth似乎无法解决问题。 Does anyone know what is causing this?
有谁知道是什么原因造成的?
For some reason when you create a path using (roundedRect rect: CGRect, cornerRadius: CGFloat)
it is not closed (despite what it says in the documentation). 出于某种原因,当您使用
(roundedRect rect: CGRect, cornerRadius: CGFloat)
创建路径时(roundedRect rect: CGRect, cornerRadius: CGFloat)
它不会关闭(尽管它在文档中说明了)。
Calling focusPath.close()
closes the path and removes the missing pixel. 调用
focusPath.close()
关闭路径并删除丢失的像素。
However, if you don't want rounded corners just use a normal rect and it will draw correctly. 但是,如果您不想要圆角,只需使用普通的矩形即可正确绘制。
let focusPath = UIBezierPath(rect: focusSize)
For anyone interested here are the resulting paths: 对于任何感兴趣的人都是结果路径:
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>
Setting the lineCap
may make the box appear correctly, but isn't fixing the issue as it just extends the visible end points and covers up the missing bit. 设置
lineCap
可能会使框显示正确,但不会解决问题,因为它只是扩展了可见的端点并掩盖了缺失的位。 Set borderLayer.lineJoin = kCALineJoinBevel
to see why this can be a problem. 设置
borderLayer.lineJoin = kCALineJoinBevel
以查看为什么这可能是个问题。
The reason you're seeing a missing pixel on your rect is because you haven't configured the lineCap
property correctly. 您在rect上看到缺少像素的原因是您没有正确配置
lineCap
属性。
Try adding this line : 尝试添加此行:
borderLayer.lineCap = kCALineCapSquare
For more on line cap (and line join which is also important to understand) see this page : http://calayer.com/core-animation/2016/05/22/cashapelayer-in-depth.html#line-cap 有关线上限的更多信息(以及线路连接,这也很重要,请参阅此页面): http : //calayer.com/core-animation/2016/05/22/cashapelayer-in-depth.html#line-cap
Yes as per the doc it should be a rect but I dont think it mentions the lineWidth 是的,根据文档它应该是一个矩形,但我不认为它提到lineWidth
This seems to be the reason why you see a pixel missing 这似乎是您看到像素丢失的原因
borderLayer.lineWidth = 2
Now when you change the width to 1 then it draws a perfect rectangle without any missing pixels 现在,当您将宽度更改为1时,它会绘制一个完美的矩形,而不会丢失任何像素
Changing the lineWidth to 10 shows considerable difference in the gap 将lineWidth更改为10表示差距相当大
The solution to your problem would be using this 你问题的解决方案就是使用它
borderLayer.lineCap = kCALineCapSquare
Check these lineCap & Line Cap Values 检查这些lineCap和Line Cap值
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.