da1lbi3 da1lbi3 - 12 days ago 11
Swift Question

Different setStroke color per UIGraphicsGetCurrentContext

I want to set an different stroke color for each UIBezierPath section. But the order is totally wrong and I don't know how to fix it.

This is what I want:

enter image description here

And this is what I get:

enter image description here

It seems like that the order is wrong. Is there a way to "bind" the color to the bezierPath and append that to the context? My code is below. Thanks!

let size = CGSize(width: 134, height:51)
UIGraphicsBeginImageContext(size)
let context = UIGraphicsGetCurrentContext()

//// Rectangle Drawing
let rectanglePath = UIBezierPath(roundedRect: CGRect(x: 0.5, y: 0.5, width: 126, height: 50), cornerRadius: 3)
UIColor.lightGray.setStroke()
rectanglePath.lineWidth = 1
rectanglePath.stroke()
let clipPath: CGPath = rectanglePath.cgPath
context?.addPath(clipPath)

//// Rectangle 2 Drawing
let rectangle2Path = UIBezierPath(roundedRect: CGRect(x: 3, y: 3, width: 121, height: 45), cornerRadius: 3)
UIColor.green.setFill()
rectangle2Path.fill()
let clipPathh: CGPath = rectangle2Path.cgPath
context?.addPath(clipPathh)

let rectangle3Path = UIBezierPath(roundedRect: CGRect(x: 128, y: 18, width: 6, height: 14), byRoundingCorners: [.topRight, .bottomRight], cornerRadii: CGSize(width: 3, height: 3))
UIColor.gray.setFill()
rectangle3Path.fill()
let clipPathhh: CGPath = rectangle3Path.cgPath
context?.addPath(clipPathhh)

context?.closePath()

// Convert to UIImage
let cgimage = context!.makeImage();
let uiimage = UIImage(cgImage: cgimage!)

// End the graphics context
UIGraphicsEndImageContext()

image.image = uiimage;

dfd dfd
Answer

Got it. Been a while since I worked with bezier paths, but a bit of playing around found the issue - it's all in the sequence. The code should be:

let size = CGSize(width: 134, height:51)
UIGraphicsBeginImageContext(size)
let context = UIGraphicsGetCurrentContext()

//// Rectangle Drawing
let rectanglePath = UIBezierPath(roundedRect: CGRect(x: 0.5, y: 0.5, width: 126, height: 50), cornerRadius: 3)
UIColor.lightGray.setStroke()
rectanglePath.lineWidth = 1
let clipPath: CGPath = rectanglePath.cgPath
context?.addPath(clipPath)
rectanglePath.stroke()

//// Rectangle 2 Drawing
let rectangle2Path = UIBezierPath(roundedRect: CGRect(x: 3, y: 3, width: 121, height: 45), cornerRadius: 3)

UIColor.green.setFill()
let clipPathh: CGPath = rectangle2Path.cgPath
context?.addPath(clipPathh)
rectangle2Path.fill()

let rectangle3Path = UIBezierPath(roundedRect: CGRect(x: 128, y: 18, width: 6, height: 14), byRoundingCorners: [.topRight, .bottomRight], cornerRadii: CGSize(width: 3, height: 3))
UIColor.gray.setFill()
let clipPathhh: CGPath = rectangle3Path.cgPath
context?.addPath(clipPathhh)
rectangle3Path.fill()

// Convert to UIImage
let cgimage = context!.makeImage();
let uiimage = UIImage(cgImage: cgimage!)

// End the graphics context
UIGraphicsEndImageContext()


imageView.image = uiimage;

Note that you do the fill/stroke after adding the path to the context. Also, note that the closePath call has no impact, as you are already giving the entire path by defining rects.

Comments