SwiftUI. How to create a rectangle with cutout circle in a top of it
Hi there.
Itโs been a long time since I posted something here.
Recently I have faced an interesting task to build using SwiftUI.
I have go the following design to follow:
Basically there are 3 layers here:
- Background full screen layer
- Phone mockup image
- (The most challenging one) White layer with the curved top part.
If there is no middle layer with the phone mockup image, which is covered by the top white one, the task is easy. Just add a rectangle and double wide circle in top and mask them.
However here we have much complicated view. We need to have a rectangle with cutout circle in the top of that rectangle. The challenging part for me was to make that circle transparent and bottom part fill with color.
For me it seemed there are a few possible solutions for this task but I have decided to stick to the following plan:
- Make a custom background view with cutout circle but only a top part. It looks like this:
2. Add all the necessary content and fill the rest of the bottom part of the view with background color that matches the above view.
So here is the code example for the view I have to achieve:
import SwiftUI
struct BackgroundView: View {
let fillColor: Color
var body: some View {
GeometryReader { geometry in
let screenWidth = geometry.size.width
let circleDiameter = screenWidth * 2
Rectangle()
.fill(fillColor)
.frame(width: geometry.size.width, height: geometry.size.height, alignment: .trailing)
.mask(
HoleShapeMask(in: CGRect(x: 0, y: -geometry.size.height/2, width: geometry.size.width*2, height: geometry.size.height)).fill(style: FillStyle(eoFill: true))
.frame(width: circleDiameter, height: circleDiameter)
)
}
}
}
func HoleShapeMask(in rect: CGRect) -> Path {
var shape = Rectangle().path(in: rect)
shape.addPath(Circle().path(in: rect))
return shape
}
#Preview {
BackgroundView(fillColor: .brown)
}
Hope this will help anyone struggling with the same issue as I had.
Cheers and happy coding to all of you!