Skip to content

ConcentricRectangle and ContainerRelativeShape

Both ConcentricRectangle (new in iOS 26) and ContainerRelativeShape reduce the corner radius accordingly when insetted in a container shape:

So what's the difference? Both need to come near rounded corners of an outer rounded .containerShape, but ConcentricRectangle needs to be near an actual corner and will only round that corner by default: (ConcentricRectangle in red, ContainerRelativeShape in yellow):

The real difference becomes visible when moving the shape just in one direction a bit:

This shape is not that practical with only one corner rounded, but the uniform version ConcentricRectangle(corners: .concentric, isUniform: true) with all the other corners getting the same rounding is quite nice:

This is mostly useful to make views rounded according to the device bezel rounded corners because SwiftUI sets a container shape accordingly.

swift
// » SwiftUI Garden
// » https://swiftui-garden.com/Shapes/ConcentricRectangle-and-ContainerRelativeShape

import SwiftUI

struct ConcentricShapeExample: View {
    var body: some View {
        ContainerExampleShape()
            .overlay(alignment: .leading) {
                ConcentricAndContainerRelativeRectangle()
                    .padding(.leading, 8)
            }
            .containerShape(RoundedRectangle(cornerRadius: 50))
    }
}

struct ContainerExampleShape: View {
    var body: some View {
        Color.blue.opacity(0.3)
            .frame(width: 300, height: 300)
            .clipShape(RoundedRectangle(cornerRadius: 50))
    }
}

struct ConcentricAndContainerRelativeRectangle: View {
    var body: some View {
        ZStack {
            ConcentricRectangle()
                .fill(Color.red.opacity(0.5))

            ContainerRelativeShape()
                .fill(Color.yellow.opacity(0.5))
        }
        .frame(width: 120, height: 120)
    }
}

#Preview {
    ConcentricShapeExample()
}
swift
// » SwiftUI Garden
// » https://swiftui-garden.com/Shapes/ConcentricRectangle-and-ContainerRelativeShape

import SwiftUI

enum Experiment: String, CaseIterable, Identifiable {
    case concentricRect
    case scrollableConcentricRect
    case uniformConcentricRect
    case containerRelative

    var title: String {
        switch self {
        case .concentricRect:
            "concentricRect"
        case .scrollableConcentricRect:
            "concentricRect (scrollable)"
        case .uniformConcentricRect:
            "concentricRect (uniform)"
        case .containerRelative:
            "containerRelative"
        }
    }

    var id: String {
        self.rawValue
    }
}

struct ConcentricShapeFullscreenExample: View {
    @State var experiment: Experiment = .concentricRect
    @State var showSheet = false

    var body: some View {
        Group {
            switch experiment {
            case .concentricRect:
                ShapeView {
                    ConcentricRectangle()
                }

            case .scrollableConcentricRect:
                ScrollView {
                    ShapeView {
                        ConcentricRectangle()
                    }
                    .frame(height: 1000)
                }

            case .uniformConcentricRect:
                ShapeView {
                    ConcentricRectangle(corners: .concentric, isUniform: true)
                }

            case .containerRelative:
                ShapeView {
                    ContainerRelativeShape()
                }
            }

        }
        .ignoresSafeArea()
        .overlay {
            VStack {
                Picker("Experiment", selection: $experiment) {
                    ForEach(Experiment.allCases, id: \.self) { experiment in
                        Text(experiment.title).tag(experiment)
                    }
                }
                .menuStyle(.button)
                .pickerStyle(.menu)

                Button("Show Sheet") {
                    self.showSheet = true
                }
            }
            .padding()
            .glassEffect()
        }
        .sheet(isPresented: $showSheet) {
            ConcentricShapeFullscreenExample()
        }

    }
}

struct ShapeView<S: Shape>: View {
    @ViewBuilder let content: () -> S

    var body: some View {
        VStack {
            HStack {
                content()
                    .fill(Color.yellow)
                    .frame(height: 80)
                    .frame(maxWidth: .infinity)

                content()
                    .fill(Color.orange)
                    .frame(height: 80)
                    .frame(maxWidth: .infinity)
            }

            content()
                .fill(Color.green)
                .frame(height: 80)
                .frame(maxWidth: .infinity)

            content()
                .fill(Color.blue)
                .frame(maxHeight: .infinity)
                .frame(maxWidth: .infinity)

        }
        .padding()
    }
}

#Preview {
    ConcentricShapeFullscreenExample()
}