Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
459 views
in Technique[技术] by (71.8m points)

swift - Multiple sheet(isPresented:) doesn't work in SwiftUI

I have this ContentView with two different modal views, so I'm using sheet(isPresented:) for both, but as it seems only the last one gets presented. How could I solve this issue? Or is it not possible to use multiple sheets on a view in SwiftUI?

struct ContentView: View {
    
    @State private var firstIsPresented = false
    @State private var secondIsPresented = false
    
    var body: some View {
        NavigationView {
            VStack(spacing: 20) {
                Button("First modal view") {
                    self.firstIsPresented.toggle()
                }
                Button ("Second modal view") {
                    self.secondIsPresented.toggle()
                }
            }
            .navigationBarTitle(Text("Multiple modal view problem"), displayMode: .inline)
            .sheet(isPresented: $firstIsPresented) {
                    Text("First modal view")
            }
            .sheet(isPresented: $secondIsPresented) {
                    Text("Only the second modal view works!")
            }
        }
    }
}

The above code compiles without warnings (Xcode 11.2.1).

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...