Skip to content

ConcentricRectangle and ContainerRelativeShape

What's the difference between ConcentricRectangle (new in iOS 26) and ContainerRelativeShape?

Both do the same for an inset rectangle, reducing the corner radius accordingly:

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()
}