如何为UIView添加白芯黑边的自定义环形虚线边框?
环形带描边虚线边框实现方案
问题分析
你之前的代码出现错位问题,核心原因是:
- 两个图层的
lineDashPattern设置不一致,导致虚线单元起始位置和长度不匹配 - 未考虑
CAShapeLayer的线宽基于路径中心线绘制的特性,缺少路径或线宽的对应调整
正确实现代码
// 1. 计算居中的环形路径 let targetSize = CGSize(width: 180, height: 180) let centerRect = CGRect( x: (self.view.bounds.width - targetSize.width) / 2, y: (self.view.bounds.height - targetSize.height) / 2, width: targetSize.width, height: targetSize.height ) // 基于线宽调整路径,确保边框贴合目标范围(黑色线宽3,向内缩1.5) let pathRect = centerRect.insetBy(dx: 3 / 2, dy: 3 / 2) let ringPath = UIBezierPath(ovalIn: pathRect).cgPath // 2. 创建黑色描边图层(外层粗虚线) let blackDashLayer = CAShapeLayer() blackDashLayer.strokeColor = UIColor.black.cgColor blackDashLayer.fillColor = nil blackDashLayer.lineDashPattern = [4, 2] // 线段长度4,空隙长度2 blackDashLayer.lineWidth = 3 // 整体线宽(包含白色填充和黑色描边) blackDashLayer.lineCap = .square // 可选:设置线段端点样式,.round为圆形端点 blackDashLayer.lineDashPhase = 0 // 确保起始位置一致 blackDashLayer.path = ringPath self.view.layer.addSublayer(blackDashLayer) // 3. 创建白色填充图层(内层细虚线,与黑色图层对齐) let whiteDashLayer = CAShapeLayer() whiteDashLayer.strokeColor = UIColor.white.cgColor whiteDashLayer.fillColor = nil whiteDashLayer.lineDashPattern = [4, 2] // 与黑色图层完全一致,保证对齐 whiteDashLayer.lineWidth = 1 // 黑色线宽减去2倍描边厚度(3 - 2*1 = 1) whiteDashLayer.lineCap = .square // 与黑色图层端点样式一致 whiteDashLayer.lineDashPhase = 0 whiteDashLayer.path = ringPath self.view.layer.addSublayer(whiteDashLayer)
关键细节说明
lineDashPattern必须在两个图层保持完全相同,才能保证虚线单元位置对齐- 路径
pathRect通过insetBy调整,确保黑色虚线的外边缘刚好贴合目标尺寸的边界 - 白色图层的线宽设置为黑色线宽减去2倍的描边厚度,让白色部分刚好位于黑色虚线的中间,形成“白色填充+黑色描边”的视觉效果
- 可选设置
lineCap为.round,可以让虚线单元呈现圆形端点样式
内容的提问来源于stack exchange,提问作者Lucas Wang
相关产品推荐
相关产品推荐

