Beberapa lembar (isPresented :) tidak berfungsi di SwiftUI


21

Saya memiliki ContentView ini dengan dua tampilan modal yang berbeda, jadi saya gunakan sheet(isPresented:)untuk keduanya, tetapi sepertinya hanya yang terakhir yang disajikan. Bagaimana saya bisa mengatasi masalah ini? Atau apakah tidak mungkin untuk menggunakan banyak sheet pada tampilan di 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!")
            }
        }
    }
}

Kode di atas dikompilasi tanpa peringatan (Xcode 11.2.1).


Anda hanya dapat memiliki satu lembar. Solusi ini menunjukkan cara memiliki lansiran berbeda yang serupa dengan situasi Anda dan mungkin dapat dengan mudah digunakan kembali stackoverflow.com/questions/58737767/…
Andrew

Jawaban:


27

Silakan coba kode di bawah ini

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!")
                }
            }
        }
    }
}

1
Solusi ini masuk akal dan dapat ditingkatkan, terima kasih!
turingtested

Mencoba kode ini dengan pernyataan switch alih-alih jika ... lain dan mendapat kesalahan "Penutupan yang berisi pernyataan aliran kontrol tidak dapat digunakan dengan pembangun fungsi 'ViewBuilder'" yang membingungkan karena bukankah jika ... apakah aliran kontrol itu?
Aaron Surrain

Terima kasih! Solusi ini Berfungsi
Adelmaer

SheetViews Anda memiliki tipe yang sama: Teks, bagaimana dengan tipe yang berbeda? Sejauh yang saya lihat, itu tidak berfungsi.
Quang Hà

@ QuangHà untuk itu perlu Anda lakukan dengan cara lain. atau Anda dapat mengambil dua atau lebih SheetViews sebagai pendekatan berbeda yang Anda miliki
Rohit Makwana

11

Kasus Anda dapat diselesaikan dengan mengikuti (diuji dengan 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)
    }
}

Saya memiliki satu Lansiran namun banyak Bool yang salah tetapi sekali benar (di luar tubuh) maka saya ingin Lansiran saya mengetahui Bool mana yang benar dan menampilkan Lansiran tertentu
Dewan

6

Dapat juga menambahkan sheet ke EmptyView yang ditempatkan di latar belakang tampilan. Ini dapat dilakukan beberapa kali:

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

3

Anda dapat melakukannya hanya dengan mengelompokkan tombol dan panggilan lembar. Jika Anda memiliki satu pimpinan dan satu trailing, sesederhana itu. Namun, jika Anda memiliki beberapa bilah navigasi di bagian depan atau belakang, Anda harus membungkusnya dalam HStack dan juga membungkus setiap tombol dengan panggilan sheet-nya dalam VStack.

Berikut adalah contoh dua tombol tambahan:

            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

1

Selain jawaban Rohit Makwana , saya menemukan cara untuk mengekstrak konten sheet ke suatu fungsi karena kompiler mengalami kesulitan mengetik-memeriksa raksasa saya View.

extension YourView {
    enum Sheet {
        case a, b
    }

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

Anda dapat menggunakannya dengan cara ini:

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

Itu membuat kode lebih bersih dan juga mengurangi tekanan kompiler Anda.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.