首页 > 解决方案 > Draw CALayer border around UIView

问题描述

I want to draw a border with open gaps around a rounded UIView.

What I currently have is this result:

enter image description here

What I want to achieve is that the gray borders are laying outside the yellow view. Now they are drawn that the middle of the gray line is still in the yellow.

I tried with a mask but then only the oudside ofcourse is cut.

My code:

struct Config {
    let start: CGFloat
    let end: CGFloat
    let color: UIColor
}

extension UIView {
    func drawBorders(for configs: [Config], lineWidth: CGFloat = 3.5) {
        let circlePath = UIBezierPath(arcCenter: CGPoint (x: self.bounds.size.width / 2,
                                                          y: self.bounds.size.height / 2),
                                      radius: self.bounds.size.width / 2,
                                      startAngle: CGFloat(-0.5 * Double.pi),
                                      endAngle: CGFloat(1.5 * Double.pi),
                                      clockwise: true)

        for config in configs {
            let circleShape = CAShapeLayer()
            circleShape.path = circlePath.cgPath
            circleShape.strokeColor = config.color.cgColor
            circleShape.fillColor = UIColor.clear.cgColor
            circleShape.lineWidth = lineWidth
            circleShape.strokeStart = config.start
            circleShape.strokeEnd = config.end

            self.layer.addSublayer(circleShape)

//            let maskLayer = CAShapeLayer()
//                 maskLayer.frame = self.bounds
//            maskLayer.path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: .allCorners, cornerRadii: CGSize(width: self.bounds.size.width / 2, height: self.bounds.size.width / 2)).cgPath
//                 self.layer.mask = maskLayer
        }
    }
}

Also added the mask code in comment to show what I have tried.

Test code:

    let roundView = UIView(frame: CGRect(x: 100, y: 100, width: 150, height: 150))
    roundView.backgroundColor = .yellow
    roundView.layer.cornerRadius = roundView.frame.size.width / 2

    let config1 = Config(start: 0.125, end: 0.25, color: .gray)
    let config2 = Config(start: 0.375, end: 0.5, color: .gray)
    let config3 = Config(start: 0.625, end: 0.75, color: .gray)
    let config4 = Config(start: 0.875, end: 1, color: .gray)

    roundView.drawBorders(for: [config1, config2, config3, config4])
    view.addSubview(roundView)

Can someone please help me out?

标签: iosswiftxcodecalayeruibezierpath

解决方案


Change your circlePath .... include linewidth in radius will resolve your issue

let circlePath = UIBezierPath(arcCenter: CGPoint (x: self.bounds.size.width / 2,
                                                          y: self.bounds.size.height / 2),
                                      radius: (self.bounds.size.width / 2) + lineWidth/2,
                                      startAngle: CGFloat(-0.5 * Double.pi),
                                      endAngle: CGFloat(1.5 * Double.pi),
                                      clockwise: true)

enter image description here


推荐阅读