简体   繁体   English

CAShapeLayer左上角缺少像素

[英]CAShapeLayer missing pixel in top-left corner

I'm using a CAShapeLayer with a UIBezierPath to draw a bordered box in a view. 我正在使用带有CAShapeLayerUIBezierPath在视图中绘制带边框的框。

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 检查这些lineCapLine Cap值

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 iOS9弹出框始终指向锚点的左上角 - iOS9 popover always points to top-left corner of anchor UIImageView作为callout的leftCalloutAccessoryView自动切换左上角 - UIImageView as callout's leftCalloutAccessoryView automatically shifts top-left corner 将UITextView占位符/文本放在左上角 - Place UITextView placeholder/text at top-left corner 如何只为UILabel的左上角设置cornerRadius? - how to set cornerRadius for only top-left corner of a UILabel? 如何在ios中将图像添加到uicollectionView单元的左上角? - How to add the image to top-left corner of uicollectionView cell in ios? 在左上角创建自定义圆角矩形按钮角? - Create custom rounded rectangle button corner on top-left? 如何在 UIView 中为左上角和右上角的圆角半径仅设置顶部、左侧和右侧的边框? - how to set boarder for only top, left and right with corner radius with top-left and top-right in UIView? 如何仅创建具有左上角和左下角半径的圆角UIButton - How to create rounded UIButton with top-left & bottom-left corner radius only 如何为 UIView 的左下角、右下角和左上角设置 cornerRadius? - how to set cornerRadius for only bottom-left,bottom-right and top-left corner of a UIView? 如何仅为 UIView 的左上角和右上角设置cornerRadius? - How to set cornerRadius for only top-left and top-right corner of a UIView?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM