仅在 UIBezierPath() 的角落有边框,lineDashPattern 中的空间错误

ios*_*dev 1 uiview cashapelayer ios swift

我尝试使用 lineDashPattern 创建一个仅在角落有边框(qrCode 样式)的视图,但线之间的空间似乎与我定义的模式不匹配。这是我的游乐场:

override func loadView() {
    let view = UIView()
    view.backgroundColor = .white
    let myView = UIView(frame: CGRect(x: 50, y: 50, width: 200, height: 200))
    myView.backgroundColor = .black
    let borderLayer = CAShapeLayer()
    let d = (myView.bounds.width / 2) as NSNumber
    borderLayer.strokeColor = UIColor.blue.cgColor
    borderLayer.lineDashPattern = [d]
    borderLayer.frame = myView.bounds
    borderLayer.fillColor = nil
    borderLayer.lineWidth = 10
    borderLayer.strokeStart = 0.1
    //borderLayer.lineDashPhase = -80
    borderLayer.path = UIBezierPath(roundedRect: myView.bounds, byRoundingCorners: .allCorners, cornerRadii: CGSize(width: 30, height: 30)).cgPath
    borderLayer.lineCap = CAShapeLayerLineCap.round
    myView.layer.addSublayer(borderLayer)
    view.addSubview(myView)
    self.view = view
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

我正在尝试使用 lineDashPhase 和 strokeStart 属性调整线条的开头,但似乎不起作用。有人能帮我吗?

Don*_*Mag 5

有趣的想法 - 在圆角矩形上使用长破折号......但我不相信你会得到你想要的结果。

您可能想像这样绘制 4 个角:

在此输入图像描述

你的路径将从以下开始:

move to: A
line to: B
arc with center: C.x B.y and clockwise from 9 o'clock to 12 o'clock 
line to: D
Run Code Online (Sandbox Code Playgroud)

然后更新你的点,并绘制右上角/右下角/左下角。

这是一个示例类:

class BracketView: UIView {
    var radius: CGFloat = 30
    var lineLength: CGFloat = 30
    var lineWidth: CGFloat = 10
    var lineColor: UIColor = .blue
    
    var shapeLayer: CAShapeLayer!
    
    override class var layerClass: AnyClass {
        return CAShapeLayer.self
    }
    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }
    func commonInit() -> Void {
        shapeLayer = self.layer as? CAShapeLayer
        shapeLayer.fillColor = UIColor.clear.cgColor
        shapeLayer.lineCap = .round
    }
    override func layoutSubviews() {
        super.layoutSubviews()
        
        // set these properties here, so we can change them if desired
        shapeLayer.strokeColor = lineColor.cgColor
        shapeLayer.lineWidth = lineWidth
        
        let pth = UIBezierPath()
        
        var ptA: CGPoint = .zero
        var ptB: CGPoint = .zero
        var ptC: CGPoint = .zero
        var ptD: CGPoint = .zero
        var arcCenter: CGPoint = .zero
        var startAngle: CGFloat = 0
        
        // top-left corner
        
        startAngle = .pi    // 9 o'clock
        
        ptA.x = bounds.minX
        ptA.y = bounds.minY + radius + lineLength
        
        ptB.x = bounds.minX
        ptB.y = bounds.minY + radius
        
        ptC.x = bounds.minX + radius
        ptC.y = bounds.minY
        
        ptD.x = bounds.minX + radius + lineLength
        ptD.y = bounds.minY

        arcCenter.x = ptC.x
        arcCenter.y = ptB.y
        
        pth.move(to: ptA)
        pth.addLine(to: ptB)
        pth.addArc(withCenter: arcCenter, radius: radius, startAngle: startAngle, endAngle: startAngle + .pi * 0.5, clockwise: true)
        pth.addLine(to: ptD)
        
        // top-right corner
        
        startAngle += (.pi * 0.5)   // 12 o'clock
        
        ptA.x = bounds.maxX - (radius + lineLength)
        ptA.y = bounds.minY
        
        ptB.x = bounds.maxX - radius
        ptB.y = bounds.minY
        
        ptC.x = bounds.maxX
        ptC.y = bounds.minY + radius
        
        ptD.x = bounds.maxX
        ptD.y = bounds.minY + radius + lineLength
        
        arcCenter.x = ptB.x
        arcCenter.y = ptC.y
        
        pth.move(to: ptA)
        pth.addLine(to: ptB)
        pth.addArc(withCenter: arcCenter, radius: radius, startAngle: startAngle, endAngle: startAngle + .pi * 0.5, clockwise: true)
        pth.addLine(to: ptD)
        
        // bottom-right corner
        
        startAngle += (.pi * 0.5)   // 3 o'clock
        
        ptA.x = bounds.maxX
        ptA.y = bounds.maxY - (radius + lineLength)
        
        ptB.x = bounds.maxX
        ptB.y = bounds.maxY - radius
        
        ptC.x = bounds.maxX - radius
        ptC.y = bounds.maxY
        
        ptD.x = bounds.maxX - (radius + lineLength)
        ptD.y = bounds.maxY
        
        arcCenter.x = ptC.x
        arcCenter.y = ptB.y
        pth.move(to: ptA)
        pth.addLine(to: ptB)
        pth.addArc(withCenter: arcCenter, radius: radius, startAngle: startAngle, endAngle: startAngle + .pi * 0.5, clockwise: true)
        
        pth.addLine(to: ptD)
        
        // bottom-left corner
        
        startAngle += (.pi * 0.5)   // 6 o'clock
        
        ptA.x = bounds.minX + radius + lineLength
        ptA.y = bounds.maxY
        
        ptB.x = bounds.minX + radius
        ptB.y = bounds.maxY
        
        ptC.x = bounds.minX
        ptC.y = bounds.maxY - radius
        
        ptD.x = bounds.minX
        ptD.y = bounds.maxY - (radius + lineLength)
        
        arcCenter.x = ptB.x
        arcCenter.y = ptC.y
        
        pth.move(to: ptA)
        pth.addLine(to: ptB)
        pth.addArc(withCenter: arcCenter, radius: radius, startAngle: startAngle, endAngle: startAngle + .pi * 0.5, clockwise: true)
        pth.addLine(to: ptD)
        
        shapeLayer.path = pth.cgPath
    }
    
}
Run Code Online (Sandbox Code Playgroud)

200 x 200 帧、绿色背景的结果:

在此输入图像描述