6

मैं UICollectionView के लिए राज्य बहाली को संभालने का सबसे अच्छा तरीका खोजने का प्रयास कर रहा हूं जिसका तत्व चारों ओर घूम सकता है। मेरा लक्ष्य यह सुनिश्चित करना है कि ऐप को पुनरारंभ करते समय संग्रह दृश्य में अंतिम बार देखा गया आइटम अभी भी दिखाई दे रहा है, भले ही आइटम चारों ओर स्थानांतरित हो जाएं। उदाहरण के लिए, आइटम ए इंडेक्स 3 पर सेल में है जब ऐप की मौत हो गई थी, और जब ऐप पुनरारंभ होता है तो मॉडल कहता है कि आइटम ए को इंडेक्स 4 पर प्रदर्शित किया जाना चाहिए, मैं चाहता हूं कि संग्रह दृश्य सेल पर ऑफसेट को प्रारंभ करने के लिए प्रारंभ करें 4.UICollectionView राज्य बहाली: स्क्रॉल स्थिति को अनुकूलित करना

मैंने सोचा था कि मेरी UICollectionViewDataSource कक्षा में UIDataSourceModelAssociation प्रोटोकॉल को लागू मेरे लिए यह ध्यान रखना होगा, documentation राज्यों के रूप में:

[UITableView और UICollectionView] सुनिश्चित करने के लिए कक्षाओं में इस प्रोटोकॉल के तरीकों का उपयोग कि एक ही डेटा ऑब्जेक्ट्स (और केवल एक ही पंक्ति अनुक्रमणिका नहीं) को देखने और चयनित में स्क्रॉल किया जाता है।

हालांकि, मैं क्या देखा है कि इस प्रोटोकॉल को लागू ठीक से चयनित सेल की indexPath बहाली के दौरान को प्रभावित करता है (जो मेरे ऐप पर महत्वपूर्ण नहीं है), लेकिन यह पुस्तक स्थिति को प्रभावित नहीं करता है। स्क्रॉल स्थिति (संग्रह दृश्य की सामग्री ऑफ़सेट) हमेशा उस जगह पर पुनर्स्थापित की जाती है जहां ऐप की हत्या हुई थी, और UICollectionViewDataSource से प्रभावित नहीं था।

मेरे पास ऐसा कामकाज है जो इस तरह दिखता है। यह मूल रूप से मॉडल एसोसिएशन प्रोटोकॉल के रूप में एक ही पैटर्न है, लेकिन मैं इसे मैन्युअल रूप से करना है:

override func encodeRestorableStateWithCoder(coder: NSCoder) { 
    let identifier = determineIdOfCurrentlyVisibleCell() 
    coder.encodeObject(identifier, forKey: "visibleCellIdentifier") 
} 

override func decodeRestorableStateWithCoder(coder: NSCoder) { 
    if let identifier = coder.decodeObjectForKey("visibleCellIdentifier") as? String { 
     if let indexPath = model.indexPathForIdentifier(identifier) { 
      collectionView.scrollToItemAtIndexPath(indexPath, atScrollPosition: .CenteredVertically, animated: false) 
     } 
    } 
} 

मैं UIDataSourceModelAssociation के उपयोग गलत किया? क्या कोई बग है? क्या यह काम करने के लिए एक और अधिक सुरुचिपूर्ण या सही तरीका है?

+0

मैं 'देख सकते हैं indexPathForElementWithModelIdentifier: ध्यान में रखते हुए: क्या मैं कर रहा हूँ एक NSValue और कहा कि बहाल करने में ऑफसेट संग्रह देखने के लिए स्क्रॉल लपेटकर है' एक ही बात करने के लिए तैयार। यह काम करता हैं? – orkenstein

+0

@orkenstein मैंने इसका उपयोग करने की कोशिश की, लेकिन यह काम नहीं किया। मेरा ओपी देखें: "इस प्रोटोकॉल को कार्यान्वित करने से पुनर्स्थापना के दौरान चयनित कोशिकाओं के इंडेक्सपैथ को सही ढंग से प्रभावित किया जाता है (जो मेरे ऐप के लिए महत्वपूर्ण नहीं है), लेकिन यह स्क्रॉल स्थिति को प्रभावित नहीं करता है।" –

उत्तर

5

जैसा कि आपने पहले ही बताया है, UIDataSourceModelAssociationUICollectionView के ऑफसेट दिखाई देने के साथ काम नहीं कर रहा है, लेकिन केवल चयनित वस्तुओं के लिए। मैंने modelIdentifierForElementAtIndexPath और indexPathForElementWithModelIdentifier दोनों पर ब्रेकपॉइंट्स सेट करने का प्रयास किया और देखा कि उन्हें केवल सेल चुनने के बाद ही बुलाया गया था। अगर मैंने अपने ऐप को पृष्ठभूमि से पहले अपने संग्रह दृश्य के चयनित कक्षों को मंजूरी दे दी है तो modelIdentifierForElementAtIndexPath कॉल नहीं किया जाएगा, लेकिन एक बार जब मैं कम से कम एक सेल को चुने गए के रूप में सेट करता। कम से कम मैं यह सत्यापित कर सकता हूं कि आप इस व्यवहार को देखकर अकेले नहीं हैं।

मुझे लगता है कि UICollectionView की विभिन्न प्रकृति की वजह से यह संभवतः सरल बिंदु पर दृश्य कोशिकाओं को स्क्रॉल करने वाला व्यवहार बनाने के लिए सीधा नहीं है, लेकिन यह स्पष्ट रूप से ऐप्पल के दस्तावेज़ में दिखाई नहीं देता है। अपने लेआउट के लिए पहले दृश्यमान सेल में पहचानकर्ता को मैन्युअल रूप से एन्कोड करना एक अच्छा विकल्प होना चाहिए।

var collectionView: UICollectionView? 

// ... 

override func encodeRestorableStateWithCoder(coder: NSCoder) { 
    if let view = collectionView, offsetValue = NSValue(CGPoint: view.contentOffset) { 
     coder.encodeObject(offsetValue, forKey: CollectionViewContentOffsetKey) 
    } 

    super.encodeRestorableStateWithCoder(coder) 
} 

override func decodeRestorableStateWithCoder(coder: NSCoder) { 
    if let offsetValue = coder.decodeObjectForKey(CollectionViewContentOffsetKey) as? NSValue { 
     collectionView?.setContentOffset(offsetValue.CGPointValue(), animated: false) 
    } 

    super.decodeRestorableStateWithCoder(coder) 
} 
+1

अच्छा विश्लेषण। मेरी समझ मे आ रहा है। –

+0

यह काम करता था, लेकिन ऑफसेट को गलत स्थान पर थोड़ा बहाल कर रहा था - नेविगेशनबार गणनाओं के साथ कुछ गलत जांचता है। – soprof

संबंधित मुद्दे