How would I draw an inverted rounded rectangle as shown below in Swift using a UIBezierPath? To clarify, I want to ONLY draw the shape in black.
While most of us would simply put a white view with rounded corners on top of the black view (it is simpler and it more accurately reflects the visual result), if you really want to draw that shape, create a UIBezierPath
that consists of the upper left arc, the upper right arc, and the add lines to the two bottom corners. E.g.
let path = UIBezierPath(
arcCenter: CGPoint(x: rect.minX + cornerRadius, y: rect.minY),
radius: cornerRadius,
startAngle: .pi,
endAngle: .pi / 2,
clockwise: false
)
path.addArc(
withCenter: CGPoint(x: rect.maxX - cornerRadius, y: rect.minY),
radius: cornerRadius,
startAngle: .pi / 2,
endAngle: 0,
clockwise: false
)
path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY))
path.addLine(to: CGPoint(x: rect.minX, y: rect.maxY))
path.close()
There are a ton of ways to render this:
CAShapeLayer
with this path
and use that as a mask (which I show below);CAShapeLayer
as a sublayer of the view’s layer
;UIImage
using UIGraphicsImageRenderer
, and fill
that UIBezierPath
;For example:
@IBDesignable class BottomView: UIView {
@IBInspectable var cornerRadius: CGFloat = 15 { didSet { setNeedsLayout() } }
override func layoutSubviews() {
super.layoutSubviews()
let path = UIBezierPath(
arcCenter: CGPoint(x: bounds.minX + cornerRadius, y: bounds.minY),
radius: cornerRadius,
startAngle: .pi,
endAngle: .pi / 2,
clockwise: false
)
path.addArc(
withCenter: CGPoint(x: bounds.maxX - cornerRadius, y: bounds.minY),
radius: cornerRadius,
startAngle: .pi / 2,
endAngle: 0,
clockwise: false
)
path.addLine(to: CGPoint(x: bounds.maxX, y: bounds.maxY))
path.addLine(to: CGPoint(x: bounds.minX, y: bounds.maxY))
path.close()
let shapeLayer = CAShapeLayer()
shapeLayer.path = path.cgPath
shapeLayer.fillColor = UIColor.white.cgColor // the color here is irrelevant; only used to define the mask
layer.mask = shapeLayer
}
}
That yields the following when I (a) add this BottomView
to my view hierarchy; and (b) set the backgroundColor
of this view to .black
(or whatever you want):
I made this @IBDesignable
so that I could either add it in Interface Builder storyboard, but you can also add it programmatically, too.
Or you can use this UIBezierPath
with any of the patterns enumerated above. Whatever works for you.