2017-03-10 27 views
3

我使用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'的所有子圖層? –

回答

5

由於某些原因,當您使用(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

2

您在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

2

是按照商務部應該是一個RECT但我不認爲它提到線寬

這似乎是爲什麼你看到一個像素損失

borderLayer.lineWidth = 2 

現在,當你改變寬度爲1,則它繪製一個完美的長方形,沒有任何丟失的像素

改變線寬10顯示了差距很大的差異

你的問題的解決方案將通過這個

borderLayer.lineCap = kCALineCapSquare 

檢查這些lineCap & Line Cap Values

+0

這很有趣,我希望如果該值設置爲0,不會繪製邊框半徑。 – Rob