我尝试在 UIView 上添加圆形虚线边框。
我想用白色制作每个破折号并用黑色描边, 比如图中的线:Styled dash line
我曾尝试使用2个CAShapeLayers来绘制边框,但它们总是不匹配。
let dashedBorderLayer = CAShapeLayer()
dashedBorderLayer.strokeColor = UIColor.black.cgColor
dashedBorderLayer.fillColor = nil
dashedBorderLayer.lineDashPattern = [4, 2]
dashedBorderLayer.lineWidth = 3
self.view.layer.addSublayer(dashedBorderLayer)
let dashedBorderLayer2 = CAShapeLayer()
dashedBorderLayer2.strokeColor = UIColor.white.cgColor
dashedBorderLayer2.fillColor = nil
dashedBorderLayer2.lineDashPattern = [2, 4]
dashedBorderLayer2.lineWidth = 2
self.view.layer.addSublayer(dashedBorderLayer2)
假设你想要的边框由路径
p
表示,想法是创建一个路径q
,这样当它被填充时,绘制的像素将与p
被描边一样带破折号。然后您可以使用 q
作为形状图层的 path
。
// suppose our border is a 150x150 square
let p = CGPath(rect: .init(x: 0, y: 0, width: 150, height: 150), transform: nil)
let q = dashStrokedPath(p)
let shapeLayer = CAShapeLayer()
shapeLayer.path = q
shapeLayer.strokeColor = UIColor.black.cgColor
shapeLayer.fillColor = UIColor.white.cgColor
shapeLayer.lineWidth = 1
dashStrokedPath
函数将p
转换为q
。这可以使用 copy(dashingWithPhase:lengths:)
和 copy(strokingWithWidth:lineCap:lineJoin:miterLimit:)
的组合来实现:
func dashStrokedPath(_ path: CGPath) -> CGPath {
// adjust the parameters here as you wish...
let strokedAndDashed = path.copy(dashingWithPhase: 5, lengths: [10, 20])
.copy(strokingWithWidth: 5, lineCap: .round, lineJoin: .round, miterLimit: 10)
return CGPath(rect: strokedAndDashed.boundingBox, transform: nil).intersection(
strokedAndDashed
)
}
请注意,作为最后一步,我将路径与其自己的边界框相交。这是为了删除看起来像自相交线的东西。没有交集,它看起来像这样:
有了交集,它看起来像这样: