Reputation: 35953
I have a view that I want to apply a clipShape
modifier to a rounded rectangle that has only the top left and bottom left rounded corners.
I am using this extension to round specific corners of some views I have.
So, I would love if I could do this:
.clipShape(Rectangle().cornerRadius(20, [.topLeft, .topRight]))
But I got error saying Rectangle must be a shape...
So I suppose I have to create something like:
struct RectangleX: Shape {
func path(in rect: CGRect) -> Path {
var radius = CGFloat.infinity
var corners = UIRectCorner.allCorners
let path = UIBezierPath(roundedRect: rect,
byRoundingCorners: corners,
cornerRadii: CGSize(width: radius,
height: radius))
return Path(path.cgPath)
}
}
but I am failing to see how do I pass the rect to this.
Upvotes: 5
Views: 6935
Reputation: 54496
The cornerRadius
modifier already uses clipShape
.
extension View {
func cornerRadius(_ radius: CGFloat, corners: UIRectCorner) -> some View {
clipShape( RoundedCorner(radius: radius, corners: corners) )
}
}
Which means that:
.clipShape(Rectangle().cornerRadius(20, [.topLeft, .topRight]))
can also be read as:
.clipShape(Rectangle().clipShape( RoundedCorner(radius: 20, corners: [.topLeft, .topRight]) ))
and you don't really need multiple clipShape
modifiers.
Try the following instead (you don't need to use clipShape
- the custom cornerRadius
extension already calls it):
.cornerRadius(20, corners: [.topLeft, .topRight])
A more complete example:
struct ContentView: View {
var body: some View {
Rectangle()
.fill(Color.red)
.frame(width: 100, height: 100)
.cornerRadius(20, corners: [.topLeft, .topRight])
}
}
Alternatively, you can use clipShape
explicitly:
.clipShape(RoundedCorner(radius: 20, corners: [.topLeft, .topRight]))
Upvotes: 4