I use this code to round my corners of UIView
:
extension UIView {
func roundCorners(_ corners: UIRectCorner, radius: CGFloat) {
let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let mask = CAShapeLayer()
mask.path = path.cgPath
self.layer.mask = mask
self.layer.masksToBounds = false
}
}
then I used view.roundCorners([.topLeft, .topRight], radius: view.frame.width/3)
Now this rounds the corners to be convex, and I want the opposite. Meaning the top corners will stay in the same points, but the line between them is rounded towards the inside of the view. I tried achieving this by calling the above function with a negative value, but this resulted with just nothing happening.
I added a picture that calrifies my goal.
How could I achieve this?
You'll need to create your own UIBezierPath
. For the concave ends, addQuadCurve(to:controlPoint:)
comes in handy.
Here I'm using the parameter depth
to control the amount of curve:
extension UIView {
func concaveEnds(depth: CGFloat) {
let width = self.bounds.width
let height = self.bounds.height
let path = UIBezierPath()
path.move(to: CGPoint.zero)
path.addLine(to: CGPoint(x: width, y: 0))
path.addQuadCurve(to: CGPoint(x: width, y: height), controlPoint: CGPoint(x: width - height * depth, y: height / 2))
path.addLine(to: CGPoint(x: 0, y: height))
path.addQuadCurve(to: CGPoint.zero, controlPoint: CGPoint(x: height * depth, y: height / 2))
let mask = CAShapeLayer()
mask.path = path.cgPath
self.layer.mask = mask
self.layer.masksToBounds = false
}
}
Demo in a Playground:
let view = UIView(frame: CGRect(x: 0, y: 0, width: 400, height: 100))
view.backgroundColor = .red
view.concaveEnds(depth: 0.4)