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)