This is an article how to round only specific corners using ContainerRelativeShape which have been appeared from iOS 14.
What is ContainerRelativeShape ?
It will round corners of SwiftUI's view with suitable radius.
Corner rounded devices and UIs are increasing such as iPhone 11 and WidgetKit and more.
Purpose
| 1. Place it in the upper left | 2. Apply ContainerRelativeShape | 3. Make only upper left corner ! |
|---|---|---|
![]() |
![]() |
![]() |
This article describes the implementation of 3.
- want to round corner to specific corners.
- want to use CornerRelativeShape of auto calculates not just rounded corner.
Code
Custom Shape
You create ContainerRelativeShapeSpecificCorner struct using Shape protocol and UIRectCorner optionset.
struct ContainerRelativeShapeSpecificCorner: Shape {
private let corners: [UIRectCorner]
init(corner: UIRectCorner...) {
self.corners = corner
}
func path(in rect: CGRect) -> Path {
var p = ContainerRelativeShape().path(in: rect)
if corners.contains(.allCorners) {
return p
}
if !corners.contains(.topLeft) {
p.addPath(Rectangle().path(in: CGRect(x: rect.origin.x, y: rect.origin.y, width: rect.width / 2, height: rect.height / 2)))
}
if !corners.contains(.topRight) {
p.addPath(Rectangle().path(in: CGRect(x: rect.origin.x + rect.width / 2, y: rect.origin.y, width: rect.width / 2, height: rect.height / 2)))
}
if !corners.contains(.bottomLeft) {
p.addPath(Rectangle().path(in: CGRect(x: rect.origin.x, y: rect.origin.y + rect.height / 2, width: rect.width / 2, height: rect.height / 2)))
}
if !corners.contains(.bottomRight) {
p.addPath(Rectangle().path(in: CGRect(x: rect.origin.x + rect.width / 2, y: rect.origin.y + rect.height / 2, width: rect.width / 2, height: rect.height / 2)))
}
return p
}
}
Usage examples
// Originally
Image("camera")
.clipShape(ContainerRelativeShape())
// This article's
Image("camera")
.clipShape(ContainerRelativeShapeSpecificCorner(corner: .topLeft, .topRight))
// Complete code sample
struct SampleView: View {
var body: some View {
Group {
Image("camera")
.resizable()
.scaledToFill()
.frame(width: 80, height: 80)
.clipShape(ContainerRelativeShapeSpecificCorner(corner: .topLeft))
}
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
.padding(8)
}
}



Top comments (0)