मैं अपने पहले iOS 14 विजेट पर काम कर रहा हूं। मुझे पता है कि विजेट ज्यादातर स्थिर होते हैं और एनिमेशन या जैसी गतिशील सामग्री नहीं दिखा सकते हैं। लेकिन क्या किसी विजेट में/दृश्यों की संख्या का लेआउट बदलना संभव है?

चूंकि मैं स्विफ्टयूआई में नया हूं, इसलिए मुझे दृश्य सामग्री को बदलने का कोई तरीका नहीं दिख रहा है।

संदर्भ:

एक टूडू ऐप मान लें जहां विजेट को अधिकतम 5 प्रविष्टियों के लिए बटन/लिंक दिखाना चाहिए। हालांकि, अगर वर्तमान में ऐप में केवल 3 प्रविष्टियां हैं, तो निश्चित रूप से विजेट केवल 3 लिंक दिखाना चाहिए।

ऐप पहले से ही टुडे विजेट प्रदान करता है। यहां मैंने विजेट दृश्य में निश्चित संख्या में प्रविष्टियों (जैसे 5) के लिए नियंत्रण (बटन) जोड़कर समस्या का समाधान किया है। यदि कम प्रविष्टियां दिखाई जानी चाहिए, तो जब विजेट अपने दृश्य को अपडेट करता है तो अप्रयुक्त नियंत्रण केवल छुपाए जाते हैं।

स्विफ्टयूआई में निश्चित संख्या में प्रविष्टियों (लिंक) के साथ एक विजेट दृश्य बनाना कोई समस्या नहीं है। लेकिन मैं अप्रयुक्त विचारों को कैसे छिपा/हटा सकता हूं?

स्विफ्टयूआई में दृश्य एक some View चर है, मुझे इसकी सामग्री को गतिशील रूप से बदलने का कोई तरीका नहीं दिखता है:

struct MyEntryView: View {
    var body: some View {
        Hstrack {
            // Item 1

            // Item 2

            ...

            // Item n
        }
    }
}
1
Andrei Herford 1 अक्टूबर 2020, 18:33

1 उत्तर

सबसे बढ़िया उत्तर

विजेट दृश्य स्थिर होते हैं लेकिन जब भी उन्हें कोई नई प्रविष्टि दी जाती है तो वे फिर से खींचे जाते हैं

एक विजेट दृश्य बनाना संभव नहीं है जो संग्रह में परिवर्तन होने पर स्वयं अपडेट हो जाएगा।

आप या तो यह कर सकते हैं:

  • पहले से प्रविष्टियाँ बनाएँ
  • या जब आप अपने संग्रह में परिवर्तनों का पता लगाते हैं तो समयरेखा को ताज़ा करें

दोनों ही मामलों में आपको एक एंट्री बनानी होगी:

struct SimpleEntry: TimelineEntry {
    let date: Date
    let items: [String]
}

और इसके आइटम को एक दृश्य में प्रदर्शित करें:

struct SimpleWidgetEntryView: View {
    var entry: SimpleProvider.Entry

    var body: some View {
        VStack {
            ForEach(entry.items, id: \.self) {
                Text($0)
            }
        }
    }
}

केवल अंतर यह है कि आप प्रविष्टियाँ कैसे बनाते हैं:

आप ऐसा कर सकते हैं:

  • अग्रिम में प्रविष्टियां बनाएं (items का आकार भिन्न हो सकता है):
func getTimeline(in context: Context, completion: @escaping (Timeline<SimpleEntry>) -> Void) {
    var entries = [SimpleEntry]()

    let currentDate = Date()

    for offset in 0 ..< 5 {
        let entryDate = Calendar.current.date(byAdding: .minute, value: offset, to: currentDate)!
        entries.append(SimpleEntry(date: entryDate, items: Array(repeating: "Test", count: offset + 1)))
    }

    let timeline = Timeline(entries: entries, policy: .atEnd)
    completion(timeline)
}
  • या वर्तमान डेटा के साथ एक एकल प्रविष्टि बनाएं और जब भी डेटा बदलता है, कॉल करके विजेट को रीफ्रेश करें:
WidgetCenter.shared.reloadAllTimelines()

(आप समयरेखा को कितनी बार पुनः लोड कर सकते हैं इसकी एक सीमा है)।

1
pawello2222 1 अक्टूबर 2020, 19:53