I made a custom shape in SwiftUI with the following code:
struct CustomShape: Shape {
func path(in rect: CGRect) -> Path {
var path = Path()
path.move(to: CGPoint(x: rect.minX, y: rect.maxY))
path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY))
path.addLine(to: CGPoint(x: rect.maxX, y: rect.minY))
path.addQuadCurve(to: CGPoint(x: 0, y: rect.minY), control: CGPoint(x: rect.midX, y: rect.minY - 25))
return path
}
}
The usage of this shape looks like the following:
CustomShape()
.fill(.ultraThickMaterial)
.frame(height: 200)
The problem is that if I try to fill it with a color it works perfectly. If I try to fill it with a material only the rectangle seems to get filled, the arc portion remains white:
Do you have an idea how to solve this?
CodePudding user response:
It seems that clipping is being applied when you are using a material, but not when you are using a color. The arc of your path is extending outside the frame of the view.
You can fix this by making the path fully contained within the rect
parameter of the shape:
func path(in rect: CGRect) -> Path {
var path = Path()
path.move(to: CGPoint(x: rect.minX, y: rect.maxY))
path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY))
path.addLine(to: CGPoint(x: rect.maxX, y: rect.minY 25))
path.addQuadCurve(to: CGPoint(x: 0, y: rect.minY 25), control: CGPoint(x: rect.midX, y: rect.minY))
path.closeSubpath()
return path
}
If you really want the material to extend outside the frame then you'll need to use a container view of some sort.
CodePudding user response:
I'd say that expected effect should be achieved with background
and clipShape
(assuming that CustomShape
is constructed correctly)
Here is a demo for better visibility (tested with Xcode 13.3 / iOS 15.4)
Image("background").overlay(
Rectangle()
.background(.thinMaterial) // << here !! (thin for demo)
.frame(height: 200)
.clipShape(CustomShape()) // << here !!
)