Skip to content

Animation when selected presentationDetent for sheet must change

FB19252983: Animation when selected presentation detent must change for a sheet because the current detent becomes unavailable

When using a .sheet() with .presentationDetents(), when the currently active presentation detent has to change because it becomes unavailable, this change is performed without an animation; I suggest to add an animation to this change, same as when the selected presentation detent is changed via Binding.

Steps to reproduce: Use the example code and switch from „Medium | Large“ to „Large“.

Example code:

swift
// » SwiftUI Garden
// » https://swiftui-garden.com/Misc/iOS-26/Animation-when-selected-presentationDetent-for-sheet-must-change

import SwiftUI

struct SheetAnimationWhenSelectedPresentationDetentMustChangeExample: View {
    var body: some View {
        Color.yellow
            .ignoresSafeArea()
            .sheet(isPresented: .constant(true)) {
                StartView()
            }
    }
}

struct StartView: View {
    enum PresentationDetentOption: CaseIterable {
        case mediumOrLarge
        case mediumOnly
        case largeOnly

        var displayName: String {
            switch self {
            case .mediumOnly:
                "Medium Only"
            case .largeOnly:
                "Large Only"
            case .mediumOrLarge:
                "Medium | Large"
            }
        }

        var detents: Set<PresentationDetent> {
            switch self {
            case .mediumOnly:
                [.medium]
            case .largeOnly:
                [.large]
            case .mediumOrLarge:
                [.medium, .large]
            }
        }
    }

    @State var selectedDetentOption: PresentationDetentOption = .mediumOnly

    var body: some View {
        VStack {
            Picker("Presentation Detents", selection: $selectedDetentOption) {
                ForEach(PresentationDetentOption.allCases, id: \.self) { option in
                    Text(option.displayName).tag(option)
                }
            }
            .pickerStyle(.segmented)
            .padding()
        }
        .presentationDetents(selectedDetentOption.detents)
    }
}

#Preview {
    SheetAnimationWhenSelectedPresentationDetentMustChangeExample()
}