CAShapeLayer在左上角丢失像素

问题描述:

我使用CAShapeLayerUIBezierPath在视图中绘制边框。CAShapeLayer在左上角丢失像素

这工作正常,但没有绘制第一个像素(顶部,左侧)。

这是我的代码:

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) 

结果(注意顶部的像素,左上角):我认为这可能与反锯齿

Weird pixel

,但玩围绕着x,y和borderWidth似乎不能解决问题。 有谁知道这是什么原因造成的?

+0

你尝试把你的层到前面?您是否尝试打印出您的'someView'的所有子图层? –

由于某些原因,当您使用(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,看看为什么这可能是一个问题。

+0

它应该导致一个矩形根据苹果的文档:https://developer.apple.com/reference/uikit/uibezierpath/1624356-init –

+0

它应该,但它不。尝试一下。 –

+0

向投票者投下这个答案;先试试吧!这是正确的 – Brett

您在rect上看到缺失像素的原因是因为您尚未正确配置lineCap属性。

尝试加入这一行:

borderLayer.lineCap = kCALineCapSquare 

更多关于线帽(并线连接,这也是很重要的理解)看到这个页面:http://calayer.com/core-animation/2016/05/22/cashapelayer-in-depth.html#line-cap

+0

这确实显示了正确的边框,但是如果roundedRect方法创建了一个类似于它的封闭路径,那么lineCap将不起作用。 –

+1

你说得对。我几乎建议在路径上使用'close()',但后来发现文档说路径已关闭。我发现它很奇怪,并建议这个。文档是错误的,这是真正的答案... – deadbeef

是按照商务部应该是一个RECT但我不认为它提到线宽

这似乎是为什么你看到一个像素损失

borderLayer.lineWidth = 2 

现在,当你改变宽度为1,则它绘制一个完美的长方形,没有任何丢失的像素

改变线宽10显示了差距很大的差异

你的问题的解决方案将通过这个

borderLayer.lineCap = kCALineCapSquare 

检查这些lineCap & Line Cap Values

+0

这很有趣,我希望如果该值设置为0,不会绘制边框半径。 – Rob