4

我正在使用 aCAShapeLayerUIBezierPath视图中绘制一个带边框的框。

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

这是我的代码:

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 似乎并不能解决问题。有谁知道是什么原因造成的?

4

3 回答 3

6

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

于 2017-03-10T13:38:49.257 回答
2

您在矩形上看到缺失像素的原因是您没有lineCap正确配置该属性。

尝试添加这一行:

borderLayer.lineCap = kCALineCapSquare

有关线帽的更多信息(以及对理解也很重要的线连接),请参阅此页面:http ://calayer.com/core-animation/2016/05/22/cashapelayer-in-depth.html#line-cap

于 2017-03-10T13:51:31.107 回答
2

是的,根据文档,它应该是一个矩形,但我认为它没有提到 lineWidth

这似乎是您看到缺少像素的原因

borderLayer.lineWidth = 2

现在,当您将宽度更改为 1 时,它会绘制一个完美的矩形,而不会丢失任何像素

将 lineWidth 更改为 10 显示间隙存在相当大的差异

您的问题的解决方案是使用这个

borderLayer.lineCap = kCALineCapSquare

检查这些lineCapLine Cap 值

于 2017-03-10T14:01:22.913 回答