I have the following code. I want a blue circle created:
class func circleFromColor(_ color: UIColor, size: CGSize = CGSize(width: 1.0, height: 1.0)) -> UIImage? {
let rect = CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height)
UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
guard let context = UIGraphicsGetCurrentContext() else { return nil }
context.setFillColor(color.cgColor)
context.fill(rect)
let radius: CGFloat = 8.0 * UIScreen.main.scale
let maskPath = UIBezierPath(roundedRect: rect, byRoundingCorners: .allCorners, cornerRadii: CGSize(width: radius, height: radius))
maskPath.addClip()
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
However every single time it returns the image is a blue SQUARE. Not a circle, what gives?
The newer way is to use UIGraphicsImageRenderer which gives you the correct point scale automatically. Also a path can fill itself so there is no need for a clipping mask:
func circleFromColor(_ color: UIColor, size: CGSize = CGSize(width: 1.0, height: 1.0)) -> UIImage? {
UIGraphicsImageRenderer(size: size).image { context in
color.setFill()
UIBezierPath(ovalIn: .init(origin: .zero, size: size)).fill()
}
}
Here is how you do it the old way:
func circleFromColor(_ color: UIColor, size: CGSize = CGSize(width: 1.0, height: 1.0)) -> UIImage? {
let rect = CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height)
UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
guard let context = UIGraphicsGetCurrentContext() else { return nil }
context.setFillColor(color.cgColor)
let radius: CGFloat = 8.0 * UIScreen.main.scale
let maskPath = UIBezierPath(roundedRect: rect, byRoundingCorners: .allCorners, cornerRadii: CGSize(width: radius, height: radius))
maskPath.addClip()
maskPath.fill()
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}