Search code examples
iosswiftcore-graphicsuibezierpathcgcontext

How do I set the line width of a UIBezierPath when drawing to a CGContext?


I'm trying to create a UIImage using a provided UIBezierPath. Unfortunately, no matter what I set setLineWidth to, the result is always a stroke of 1 point:

extension UIBezierPath {
    func image(fillColor: UIColor, strokeColor: UIColor) -> UIImage? {
        UIGraphicsBeginImageContextWithOptions(bounds.size, false, 1.0)
        guard let context = UIGraphicsGetCurrentContext() else {
            return nil
        }

        context.setLineWidth(10)
        context.setFillColor(fillColor.cgColor)
        context.setStrokeColor(strokeColor.cgColor)

        self.fill()
        self.stroke()

        let image = UIGraphicsGetImageFromCurrentImageContext()

        UIGraphicsEndImageContext()

        return image
    }
}

Trying this out in a test project with a circle, for example:

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        let imageView = UIImageView()
        imageView.frame = CGRect(x: 100, y: 100, width: 100, height: 100)
        view.addSubview(imageView)

        let bezierPath = UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: 100, height: 100))

        let image = bezierPath.image(fillColor: UIColor.blue, strokeColor: UIColor.red)

        imageView.image = image
    }
}

No matter what I set setLineWidth to, it always appears to be 1 point.

enter image description here


Solution

  • You are calling stroke on the UIBezierPath, so you need to set the lineWidth property of that using self.lineWidth = 10.

    extension UIBezierPath {
        func image(fillColor: UIColor, strokeColor: UIColor) -> UIImage? {
            UIGraphicsBeginImageContextWithOptions(bounds.size, false, 1.0)
            guard let context = UIGraphicsGetCurrentContext() else {
                return nil
            }
    
            context.setFillColor(fillColor.cgColor)
            self.lineWidth = 10
            context.setStrokeColor(strokeColor.cgColor)
    
            self.fill()
            self.stroke()
    
            let image = UIGraphicsGetImageFromCurrentImageContext()
    
            UIGraphicsEndImageContext()
    
            return image
        }
    }