Draw iOS 7-Style Squircle Programmatically

Draw iOS 7-style squircle programmatically

in iOS 13/ Xcode 11 you can now use CALayerCornerCurve

Example

yourLayer.cornerCurve = CALayerCornerCurve.continuous

source: https://developer.apple.com/documentation/quartzcore/calayercornercurve

is there a public api for getting the fancier rounded corners in modern iOS?

Now in iOS 13 and Xcode 11, you can use CALayerCornerCurve

Sample usage:

yourLayer.cornerCurve = CALayerCornerCurve.continuous

Create a rounded inflated square]

The easy way to do it is to use a mask and apply it to your image.

 - (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage {

CGImageRef maskRef = maskImage.CGImage;

CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
CGImageGetHeight(maskRef),
CGImageGetBitsPerComponent(maskRef),
CGImageGetBitsPerPixel(maskRef),
CGImageGetBytesPerRow(maskRef),
CGImageGetDataProvider(maskRef), NULL, false);

CGImageRef masked = CGImageCreateWithMask([image CGImage], mask);
return [UIImage imageWithCGImage:masked];

}

See this tutorial : http://iosdevelopertips.com/cocoa/how-to-mask-an-image.html#comment-47347

And the stackoverflow topic about your issue:
How to Mask an UIImageView

How to draw a rectangle and fill it with color based on battery level

This is a starting point.

Paste the code in a Playground and click on Show Result at the end of the last line

class LevelView : UIView {

init(frame: CGRect, level: CGFloat) {
super.init(frame: frame)
self.layer.borderWidth = 1.0
let levelLayer = CAShapeLayer()
levelLayer.path = UIBezierPath(roundedRect: CGRect(x: frame.origin.x,
y: frame.origin.y,
width: frame.width * level,
height: frame.height),
cornerRadius: 0).cgPath
levelLayer.fillColor = UIColor.red.cgColor
self.layer.addSublayer(levelLayer)

}

required init?(coder aDecoder: NSCoder) {
fatalError("Required, but Will not be called in a Playground")
}
}

let view = LevelView(frame: CGRect(x: 0, y: 0, width: 64, height: 32), level: 0.75)

Draw a rectangle with an arc cut on one side

// Set fill color to red
CGContextSetRGBFillColor(context, 1.0, 0.0, 0.0, 1.0);

// Move to the upper-left corner of the rect
CGContextMoveToPoint(context, CGRectGetMinX(rect), CGRectGetMinY(rect));

// Add a line to the left side of the hole
CGContextAddLineToPoint(context, CGRectGetMidX(rect) - holeRadius, CGRectGetMinY(rect));

// Add the semi-circular hole
CGContextAddArc(context, CGRectGetMidX(rect), CGRectGetMinY(rect), holeRadius, M_PI, 0, 1);

// Add a line to the top-right corner
CGContextAddLineToPoint(context, CGRectGetMaxX(rect), CGRectGetMinY(rect));

// Add the remaining sides of the rectangle
CGContextAddLineToPoint(context, CGRectGetMaxX(rect), CGRectGetMinY(rect));
CGContextAddLineToPoint(context, CGRectGetMaxX(rect), CGRectGetMaxY(rect));
CGContextAddLineToPoint(context, CGRectGetMinX(rect), CGRectGetMaxY(rect));

// Close path and fill with current fill color
CGContextClosePath(context);
CGContextFillPath(context);

Resulting image

Now, the really fun part is figuring out how to make it an elliptical hole instead of a circular one. That I leave to the reader :)

CGPathRef and PDF

SVGKit doesn't work the exact same as I need either. Although I should say it is nicely done. There are also other resources, that I found and I'll leave them here for future references, if anyone stops by this post and is looking for a solution.

Converting SVG Paths to Objective-C Paths Good for simple paths; strokes and fills can be manipulated later by using protocols. Complex paths get mixed up.

SVGKit Good for creating images and animate them later through the course of the program. However, strokes, fills, paths can not be manipulated.

Opacity You can export as source code, hence you have more control over strokes, paths, and fills. As the path gets more complex, it is harder to manage the code manually. The other problem is by the time of export, the program adds resolution-dependent codes. It can be a pain to go through about 300+ lines of code to fix it so that it is not resolution dependent. By the final product wouldn't be mixed up, and can be manipulated by protocols. Layers are CGLayers, not CALayers.



Related Topics



Leave a reply



Submit