Multiple sheet(isPresented:) doesn’t work in SwiftUI

UPD

Starting from Xcode 12.5.0 Beta 3 (3 March 2021) this question makes no sense anymore as it is possible now to have multiple .sheet(isPresented:) or .fullScreenCover(isPresented:) in a row and the code presented in the question will work just fine.

Nevertheless I find this answer still valid as it organizes the sheets very well and makes the code clean and much more readable – you have one source of truth instead of a couple of independent booleans

The actual answer

Best way to do it, which also works for iOS 14:

enum ActiveSheet: Identifiable {
    case first, second
    
    var id: Int {
        hashValue
    }
}

struct YourView: View {
    @State var activeSheet: ActiveSheet?

    var body: some View {
        VStack {
            Button {
                activeSheet = .first
            } label: {
                Text("Activate first sheet")
            }

            Button {
                activeSheet = .second
            } label: {
                Text("Activate second sheet")
            }
        }
        .sheet(item: $activeSheet) { item in
            switch item {
            case .first:
                FirstView()
            case .second:
                SecondView()
            }
        }
    }
}

Read more here: https://developer.apple.com/documentation/swiftui/view/sheet(item:ondismiss:content:)

To hide the sheet just set activeSheet = nil

Bonus:
If you want your sheet to be fullscreen, then use the very same code, but instead of .sheet write .fullScreenCover

Leave a Comment