user-interfaceroundingswiftuicornerradius

How to round specific corners of a View?


I know you can use .cornerRadius() to round all the corners of a SwiftUI view but is there a way to round only specific corners such as the top?


Solution

  • Demo (Source code is available at the end of the post)

    Demo Image

    iOS 16+ built-in modifier (Xcode 15 needed)

    Clip the view using the new UnevenRoundedRectangle:

    .clipShape(
        .rect(
            topLeadingRadius: 0,
            bottomLeadingRadius: 20,
            bottomTrailingRadius: 0,
            topTrailingRadius: 20
        )
    )
    

    ⚠️ Note: Although it works from iOS 16, .rect needs Xcode 15 to be available.


    iOS 13+

    You can use it like a normal modifier:

    .cornerRadius(20, corners: [.topLeft, .bottomRight])
    

    You need to implement a simple extension on View like this:

    extension View {
        func cornerRadius(_ radius: CGFloat, corners: UIRectCorner) -> some View {
            clipShape( RoundedCorner(radius: radius, corners: corners) )
        }
    }
    

    And here is the struct behind this:

    struct RoundedCorner: Shape {
        let radius: CGFloat
        let corners: UIRectCorner
    
        init(radius: CGFloat = .infinity, corners: UIRectCorner = .allCorners) {
            self.radius = radius
            self.corners = corners
        }
    
        func path(in rect: CGRect) -> Path {
            let path = UIBezierPath(roundedRect: rect, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
            return Path(path.cgPath)
        }
    }
    

    You can also use the shape directly as a clipping mask.


    Sample Project:

    iOS 13 - Source code on gist Sample iOS 14


    iOS 16 - Source code on gist Sample iOS 16