2012-11-07 33 views
66

मेरी प्रोजेक्ट में मैं आइकन के ग्रिड को प्रदर्शित करने के लिए UICollectionView का उपयोग करता हूं।UICollectionView डेटा परिवर्तन को एनिमेट करें

उपयोगकर्ता एक सेगमेंट नियंत्रण पर क्लिक करके ऑर्डरिंग को बदलने में सक्षम है जो विभिन्न एनएसएसोर्ट डिस्क्रिप्टर के साथ कोर डेटा से लाने को कॉल करता है।

डेटा की मात्रा हमेशा एक ही है, बस विभिन्न वर्गों/पंक्तियों में समाप्त:

- (IBAction)sortSegmentedControlChanged:(id)sender { 

    _fetchedResultsController = nil; 
    _fetchedResultsController = [self newFetchResultsControllerForSort]; 

    NSError *error; 
    if (![self.fetchedResultsController performFetch:&error]) { 
     NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
    } 

    [self.collectionView reloadData]; 
} 

समस्या यह है कि reloadData परिवर्तन चेतन नहीं करता है, UICollectionView सिर्फ नए डेटा से खुलेगी ।

क्या मुझे ट्रैक रखना चाहिए कि कौन सा इंडेक्सपैथ एक सेल पहले और बाद में बदल गया था, और परिवर्तन के लिए एनीमेशन निष्पादित करने के लिए [self.collectionView moveItemAtIndexPath: toIndexPath:] का उपयोग करें या बेहतर तरीका है?

मैं बहुत उपवर्गीकरण collectionViews में नहीं मिला तो किसी भी मदद महान हो जाएगा ...

धन्यवाद, विधेयक।

+0

पर देखा आप की कोशिश की है एनीमेशन ब्लॉक में 'reloadData' कॉल को लपेटना? – simon

उत्तर

58

reloadData एनिमेट नहीं करता है, और न ही यह UIView एनीमेशन ब्लॉक में डालते समय विश्वसनीय रूप से ऐसा करता है।

[self.collectionView performBatchUpdates:^{ 
    [self.collectionView reloadData]; 
} completion:^(BOOL finished) {}]; 
+4

हाँ, ऐसा लगता है कि काम करता है, लेकिन केवल अगर आपने अनुभाग संख्याएं सहेजी हैं ... अन्यथा मुझे "खंडों की अवैध संख्या" प्राप्त हो रही है। अद्यतन के बाद संग्रह दृश्य में निहित अनुभागों की संख्या (10) संख्या के बराबर होनी चाहिए अद्यतन से पहले संग्रह दृश्य में निहित अनुभागों (16) "। मुझे अनुभागों को मैन्युअल रूप से सम्मिलित/हटा देना है ... वैसे भी स्वीकार किया गया है! धन्यवाद। – Nimrod7

+1

"मैन्युअल रूप से", क्या आपका मतलब UICollectionView के insertSections/moveSection के माध्यम से है: toSection/deleteSections कॉल? या कुछ और? (क्षमा करें, अब तक यूआईसीओलेक्शन व्यू के मेरे उपयोग में वर्गों की स्थिर संख्या है) – Stripes

+1

हां उन तरीकों के माध्यम से ... विचार को लागू करने के लिए थोड़ा मुश्किल है, आपको अद्यतन से पहले और बाद में इंडेक्सपाथ याद रखना होगा, जो आंकड़ा डाला गया है, या स्थानांतरित ... – Nimrod7

130

-performBatchUpdates: में -reloadData रैपिंग एक खंड संग्रह दृश्य चेतन करने के लिए कारण प्रतीत नहीं होता है: यह एक UICollecitonView performBatchUpdates ब्लॉक में हो, तो अधिक की तरह कुछ करने की कोशिश करना चाहता है।

[self.collectionView performBatchUpdates:^{ 
    [self.collectionView reloadData]; 
} completion:nil]; 

हालांकि, इस कोड काम करता है:

[self.collectionView performBatchUpdates:^{ 
    [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]]; 
} completion:nil]; 
+8

प्रलेखन से नोट: आपको एनीमेशन ब्लॉक के बीच में पुनः लोड डेटा विधि को कॉल नहीं करना चाहिए जहां आइटम डाले जा रहे हैं या हटाए गए हैं। सम्मिलन और हटाना स्वचालित रूप से तालिका के डेटा को उचित रूप से अपडेट करने का कारण बनता है। –

+0

मुझे लगता है कि यह सही जवाब होना चाहिए। क्योंकि यह मेरे लिए काम किया। मेरे पास केवल 1 अनुभाग है और यह सही उत्तर नहीं दे रहा है। –

+0

यदि आप भी सम्मिलित कर रहे हैं तो काम नहीं करता है। सॉर्टिंग एनीमेशन ओवरराइड होगा। –

2

सहायता पाठ का कहना है:

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

मुझे लगता है कि मुख्य भाग "संग्रह दृश्य को वर्तमान में किसी भी दृश्यमान आइटम को त्यागने का कारण बनता है"। यह उन वस्तुओं के आंदोलन को एनिमेट करने जा रहा है जो इसे छोड़ दिया गया है?

[self.collectionView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, self.collectionView.numberOfSections)]]; 

स्विफ्ट 3

let range = Range(uncheckedBounds: (0, collectionView.numberOfSections)) 
let indexSet = IndexSet(integersIn: range) 
collectionView.reloadSections(indexSet) 
47

यह है कि मैं क्या सभी वर्गों के पुनः लोड चेतन करने के लिए किया था UICollectionViewCell एनिमेशन के विभिन्न तरीकों के बहुत विस्तृत स्पष्टीकरण।

2

आप अधिक नियंत्रण और अनुकूलन सुविधा की जांच this चाहते हैं, यह एक में शामिल हैं:

4

performBatchUpdates:completion: ब्लॉक के अंदर पूरे संग्रह दृश्य को फिर से लोड करना आईओएस 9 सिम्युलेटर पर मेरे लिए एक गड़बड़ एनीमेशन करता है। यदि आपके पास एक विशिष्ट UICollectionViewCell है, तो आप हटाना चाहते हैं, या यदि आपके पास इंडेक्स पथ है, तो आप उस ब्लॉक में deleteItemsAtIndexPaths: पर कॉल कर सकते हैं। deleteItemsAtIndexPaths: का उपयोग करके, यह एक चिकनी और अच्छी एनीमेशन करता है।

UICollectionViewCell* cellToDelete = /* ... */; 
NSIndexPath* indexPathToDelete = /* ... */; 

[self.collectionView performBatchUpdates:^{ 
    [self.collectionView deleteItemsAtIndexPaths:@[[self.collectionView indexPathForCell:cell]]]; 
    // or... 
    [self.collectionView deleteItemsAtIndexPaths:@[indexPath]]; 
} completion:nil]; 
+1

बस मेरे मामले में क्रैश समस्या हल करने वाली चीज़ का उल्लेख करना चाहते हैं, डेटास्रोत अपडेट करें (यानी।सेक्शन/आइटम गिनती) कॉल करने से पहले संग्रह दृश्य पर अद्यतन। – ViruMax

-2

तेज उपयोगकर्ताओं के लिए यह काम आता है -

collectionView.performBatchUpdates({ 

      self.collectionView.reloadSections(NSIndexSet(index: index)) 

      }, completion: nil) 
1

स्विफ्ट उपयोगकर्ताओं के लिए, यदि आपके collectionview केवल एक अनुभाग है:

self.collectionView.performBatchUpdates({ 
        let indexSet = IndexSet(integersIn: 0...0) 
        self.collectionView.reloadSections(indexSet) 
       }, completion: nil) 

रूप https://stackoverflow.com/a/42001389/4455570

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