[swift] SwiftUI에서 여러 시트 (isPresented :)가 작동하지 않습니다

이 ContentView에는 두 개의 다른 모달 뷰가 있으므로 두 가지 sheet(isPresented:)모두에 사용하고 있지만 마지막 뷰 만 표시되는 것처럼 보입니다. 이 문제를 어떻게 해결할 수 있습니까? 아니면 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!")
            }
        }
    }
}

위 코드는 경고없이 컴파일됩니다 (Xcode 11.2.1).



답변

아래 코드를 시도하십시오

enum ActiveSheet {
   case first, second
}

struct ContentView: View {

    @State private var showSheet = false
    @State private var activeSheet: ActiveSheet = .first

    var body: some View {

        NavigationView {
            VStack(spacing: 20) {
                Button("First modal view") {
                    self.showSheet = true
                    self.activeSheet = .first
                }
                Button ("Second modal view") {
                    self.showSheet = true
                    self.activeSheet = .second
                }
            }
            .navigationBarTitle(Text("Multiple modal view problem"), displayMode: .inline)
            .sheet(isPresented: $showSheet) {
                if self.activeSheet == .first {
                    Text("First modal view")
                }
                else {
                    Text("Only the second modal view works!")
                }
            }
        }
    }
}


답변

당신은 사건을 다음과 같이 해결할 수 있습니다 (Xcode 11.2로 테스트 됨)

var body: some View {

    NavigationView {
        VStack(spacing: 20) {
            Button("First modal view") {
                self.firstIsPresented.toggle()
            }
            .sheet(isPresented: $firstIsPresented) {
                    Text("First modal view")
            }
            Button ("Second modal view") {
                self.secondIsPresented.toggle()
            }
            .sheet(isPresented: $secondIsPresented) {
                    Text("Only the second modal view works!")
            }
        }
        .navigationBarTitle(Text("Multiple modal view problem"), displayMode: .inline)
    }
}


답변

뷰의 배경에 배치 된 EmptyView에 시트를 추가 할 수도 있습니다. 여러 번 수행 할 수 있습니다.

  .background(EmptyView()
        .sheet(isPresented: isPresented, content: content))


답변

버튼과 .sheet 호출을 그룹화하여 간단히 수행 할 수 있습니다. 하나의 선행과 하나의 후행이 있으면 간단합니다. 그러나 선행 또는 후행에 여러 탐색 표시 줄 항목이있는 경우이를 HStack으로 랩핑하고 각 단추를 시트 호출로 VStack으로 랩핑해야합니다.

두 개의 후행 버튼의 예는 다음과 같습니다.

            trailing:
            HStack {
                VStack {
                    Button(
                        action: {
                            self.showOne.toggle()
                    }
                    ) {
                        Image(systemName: "camera")
                    }
                    .sheet(isPresented: self.$showOne) {
                        OneView().environment(\.managedObjectContext, self.managedObjectContext)
                    }
                }//showOne vstack

                VStack {
                    Button(
                        action: {
                            self.showTwo.toggle()
                    }
                    ) {
                        Image(systemName: "film")
                    }
                    .sheet(isPresented: self.$showTwo) {
                        TwoView().environment(\.managedObjectContext, self.managedObjectContext)
                    }
                }//show two vstack
            }//nav bar button hstack


답변

Rohit Makwana의 답변 외에도 컴파일러가 거대한 형식 검사에 어려움을 겪어 시트 내용을 함수로 추출하는 방법을 찾았습니다 View.

extension YourView {
    enum Sheet {
        case a, b
    }

    @ViewBuilder func sheetContent() -> some View {
        if activeSheet == .a {
            A()
        } else if activeSheet == .b {
            B()
        }
    }
}

이 방법으로 사용할 수 있습니다 :

.sheet(isPresented: $isSheetPresented, content: sheetContent)

코드를 더 깨끗하게 만들고 컴파일러의 스트레스를 덜어줍니다.


답변