क्या व्यू अपडेट को ट्रिगर करने के लिए स्विफ्टयू डायनेमिकप्रॉपर्टी प्रॉपर्टी रैपर के आंतरिक अपडेट की उम्मीद करना सही है?


10

मैं SwiftUI द्वारा समर्थित एक कस्टम प्रॉपर्टी रैपर बनाने का प्रयास कर रहा हूं, जिसका अर्थ है कि संबंधित गुण मानों में परिवर्तन करने से SwiftUI दृश्य को अपडेट किया जाएगा। यहाँ मेरे पास एक सरलीकृत संस्करण है:

@propertyWrapper
public struct Foo: DynamicProperty {
    @ObservedObject var observed: SomeObservedObject

    public var wrappedValue: [SomeValue] {
        return observed.value
    }
}

मैं देखता हूं कि भले ही मैं ObservedObjectअपने कस्टम प्रॉपर्टी रैपर के अंदर समाहित हूं, फिर भी स्विफ्टयूआई SomeObservedObjectजब तक बदलावों को पकड़ती है :

  • मेरी संपत्ति आवरण एक संरचना है
  • मेरी संपत्ति रैपर के अनुरूप है DynamicProperty

दुर्भाग्य से डॉक्स विरल हैं और मेरे पास यह बताने में मुश्किल समय है कि क्या यह केवल वर्तमान स्विफ्टयूआई कार्यान्वयन के साथ भाग्य से बाहर काम करता है।

डॉक्स के DynamicProperty(Xcode के भीतर, ऑनलाइन नहीं) यह दर्शाता है कि ऐसी संपत्ति एक संपत्ति है जो बाहर से बदलकर देखने के लिए बदल जाती है, लेकिन जब आप इस प्रोटोकॉल पर अपने प्रकार के अनुरूप होते हैं, तो इसके बारे में कोई गारंटी नहीं होती है।

क्या मैं भविष्य में स्विफ्टयूआई रिलीज में काम जारी रखने की उम्मीद कर सकता हूं?


4
यह स्पष्ट नहीं है कि इस विषय की उम्मीद क्या है ... एक आखिरी सवाल पर जवाब दें? क्या आप वास्तव में विश्वास करेंगे कि यदि कोई व्यक्ति "हाँ, निश्चित रूप से, आप उम्मीद कर सकते हैं" का उत्तर दें? ))
अस्पररी

जवाबों:


6

ठीक है ... यहां भी इसी तरह की चीज पाने के लिए वैकल्पिक तरीका है ... लेकिन जैसा कि संरचना केवल DynamicPropertyचारों ओर लिपटी हुई है @State(ताज़ा देखने के लिए मजबूर करने के लिए)।

यह सरल आवरण है, लेकिन निम्नलिखित दृश्य ताज़ा करने के साथ किसी भी कस्टम गणना को बाधित करने की संभावना देता है ... और जैसा कि केवल मूल्य प्रकार का उपयोग करके कहा गया है।

यहाँ डेमो है (Xcode 11.2 / iOS 13.2 के साथ परीक्षण किया गया):

@State पर आवरण के रूप में DynamicProperty

यहाँ कोड है:

import SwiftUI

@propertyWrapper
struct Refreshing<Value> : DynamicProperty {
    let storage: State<Value>

    init(wrappedValue value: Value) {
        self.storage = State<Value>(initialValue: value)
    }

    public var wrappedValue: Value {
        get { storage.wrappedValue }

        nonmutating set { self.process(newValue) }
    }

    public var projectedValue: Binding<Value> {
        storage.projectedValue
    }

    private func process(_ value: Value) {
        // do some something here or in background queue
        DispatchQueue.main.async {
            self.storage.wrappedValue = value
        }
    }

}


struct TestPropertyWrapper: View {

    @Refreshing var counter: Int = 1
    var body: some View {
        VStack {
            Text("Value: \(counter)")
            Divider()
            Button("Increase") {
                self.counter += 1
            }
        }
    }
}

struct TestPropertyWrapper_Previews: PreviewProvider {
    static var previews: some View {
        TestPropertyWrapper()
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.