Search code examples
iosswiftuiviewuibezierpathcashapelayer

BezierPath sublayer does not wrap around the whole UIView


I'm currently trying to make a dotted border around my UIView. I referred to a previous post: Dashed line border around UIView

The left side of the UIView gets the red dotted lines but the right side misses the edge.

Left side This is left side

Right side This is right side

Here is my code which I am executing in viewDidLoad:

myview.backgroundColor = UIColor.lightGray
myview.layer.cornerRadius = 4

let dottedBorder = CAShapeLayer()
dottedBorder.strokeColor = UIColor.red.cgColor
dottedBorder.lineDashPattern = [4, 4]
dottedBorder.frame = myview.bounds
dottedBorder.fillColor = nil
dottedBorder.path = UIBezierPath(roundedRect: myview.bounds, byRoundingCorners: .allCorners, cornerRadii: CGSize(width: 4, height: 4)).cgPath
        
myview.layer.addSublayer(dottedBorder)

Solution

  • Assuming you're using autolayout, you shouldn't depend on the view size inside viewDidLoad, because usually it equals you storyboard device size(selected is SB editor), not the real device one.

    Anyway, it may change in future. All calculations depending on frame/bounds needs to be done inside viewDidLayoutSubviews. Something like this:

    private let dottedBorder = CAShapeLayer()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        dottedBorder.strokeColor = UIColor.red.cgColor
        dottedBorder.lineDashPattern = [4, 4]
        dottedBorder.fillColor = nil
        myview.layer.addSublayer(dottedBorder)
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
    
        dottedBorder.frame = myview.bounds
        dottedBorder.path = UIBezierPath(roundedRect: myview.bounds, byRoundingCorners: .allCorners, cornerRadii: CGSize(width: 4, height: 4)).cgPath
    }