एकाधिक पत्रक (isPresented :) SwiftUI में काम नहीं करता है


21

मेरे पास यह ContentView दो अलग-अलग मोडल दृश्यों के साथ है, इसलिए मैं sheet(isPresented:)दोनों के लिए उपयोग कर रहा हूं , लेकिन जैसा कि लगता है कि केवल अंतिम प्रस्तुत किया जाता है। मैं इस मुद्दे को कैसे हल कर सकता हूं? या स्विफ्टयूआई में एक दृश्य पर कई शीट का उपयोग करना संभव नहीं है?

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)।


आपके पास केवल एक शीट हो सकती है। यह समाधान दिखाता है कि अलग-अलग अलर्ट कैसे हैं जो आपकी स्थिति के समान है और संभवतः आसानी से पुनर्निर्मित किया जा सकता है stackoverflow.com/questions/58737767/...
एंड्रयू

जवाबों:


25

कृपया नीचे कोड का प्रयास करें

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
यह समाधान समझ में आता है और स्केल कर सकता है, धन्यवाद!
turingtested

इस कोड को स्विच स्टेटमेंट के बजाय यदि ... और है, तो त्रुटि मिली "कंट्रोल फ्लो युक्त कंट्रोल फ्लो स्टेटमेंट का उपयोग फंक्शन बिल्डर 'व्यूबर्स्टल" के साथ नहीं किया जा सकता है, जो कि चकरा देने वाला था क्योंकि यदि नहीं ... तो कंट्रोल फ्लो है?
आरोन सुरेन

धन्यवाद! यह समाधान काम करता है
एडेलमेर

आपके शीट व्यू में एक ही प्रकार है: पाठ, विभिन्न प्रकार के बारे में कैसे? जहाँ तक मैं देख रहा हूँ, यह काम नहीं कर रहा है।
क्वांग एचए

@ QuangHà इसके लिए आपको दूसरे तरीके से करने की जरूरत है। या आप अलग-अलग दृष्टिकोण के रूप में दो या अधिक शीट व्यू ले सकते हैं
रोहित मकवाना

11

आपको मामला निम्नलिखित द्वारा हल किया जा सकता है (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)
    }
}

मेरे पास एक अलर्ट है, लेकिन कई बूल हैं जो झूठे हैं, लेकिन एक बार सच है (शरीर के बाहर) तो मैं चाहता हूं कि मेरा अलर्ट पता चले कि कौन सा बूल सच है और एक निश्चित अलर्ट दिखाने के लिए
दीवान

6

दृश्य की पृष्ठभूमि में रखी गई EmptyView में शीट को भी जोड़ सकते हैं। यह कई बार किया जा सकता है:

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

3

आप बस बटन और .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

1

रोहित मकवाना के जवाब के अलावा , मुझे एक फ़ंक्शन में शीट सामग्री को निकालने का एक तरीका मिला, क्योंकि कंपाइलर एक कठिन समय टाइप कर रहा था, जो मेरी विशालता की जाँच कर रहा था 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)

यह कोड को क्लीनर बनाता है और आपके कंपाइलर के तनाव से भी छुटकारा दिलाता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.