2012-11-21 10 views
15

क्या किसी ने इस समस्या का एक सभ्य उत्तर देखा है?प्रारंभिक LayoutAttributesForAppearingItemAtIndexPath सभी दृश्यमान कोशिकाओं के लिए निकाल दिया गया, न केवल कक्ष डाला

initialLayoutAttributesForAppearingItemAtIndexPath सभी दृश्यमान कोशिकाओं के लिए बुलाया जा रहा है, न केवल सेल डाला जा रहा है। Apple's own docs के अनुसार:

स्थानांतरित वस्तुओं के लिए, संग्रह दृश्य आइटम के अद्यतन लेआउट विशेषताओं को पुनर्प्राप्त करने के लिए मानक विधियों का उपयोग करता है। आइटम नहीं डाला गया या हटाया जा रहा है के लिए, संग्रह दृश्य कॉल कुछ अलग अलग तरीकों, जो आपको उचित लेआउट जानकारी

कौन क्या हो रहा है की तरह ध्वनि नहीं करता है प्रदान करने के लिए ओवरराइड करना चाहिए ... अन्य कोशिकाओं नहीं किया जा रहा है डाला गया, उन्हें स्थानांतरित किया जा रहा है, लेकिन को स्थानांतरित करने के लिए initialLayoutAttributesForAppearingItemAtIndexPath पर कॉल कर रहा है।

मैंने prepareForCollectionViewUpdates: का उपयोग करके पता लगाया है कि कौन सा इंडेक्सपैथ अपडेट किया जा रहा है और केवल उन्हें बदल रहा है, लेकिन यह थोड़ा विचित्र लगता है कि यह अपने स्वयं के दस्तावेज़ों को फिर से चला रहा है। क्या किसी और को इसके चारों ओर एक बेहतर तरीका मिला है?

+0

मुझे समझने में कठिनाई आ रही है यह भी। जब भी मैं संग्रह दृश्य में परिवर्तन करता हूं, तब सभी दृश्यमान कोशिकाओं को फिर से लोड किया जा रहा है, और यह स्पष्ट नहीं है कि इससे कैसे बचें। जब उपयोगकर्ता एक सेक्शन में सेल को टैप करता है, तो टैप किए गए सेल में बदलाव को एनिमेट करते समय मैं दूसरे सेक्शन को पुनः लोड करता हूं। रीलोड मेरे एनिमेशन में बाधा डाल रहा है, और मुझे इसके आसपास काम करने का कोई तरीका नहीं मिल रहा है। – CharlieMezak

उत्तर

9

आप अकेले नहीं हैं। UICollectionViewLayout हेडर फ़ाइल टिप्पणियां चीजों को थोड़ा स्पष्ट बनाती हैं।

स्क्रीन पर प्रत्येक तत्व अमान्यकरण से पहले के लिए, finalLayoutAttributesForDisappearingXXX कहा जाएगा और क्या उन अंतिम गुण के लिए स्क्रीन पर है से एक एनीमेशन सेटअप।

अमान्यकरण स्क्रीन पर प्रत्येक तत्व के लिए, initialLayoutAttributesForAppearingXXX एक एक एनीमेशन क्या स्क्रीन पर समाप्त होता है करने के लिए उन प्रारंभिक विशेषताओं से सेटअप बुलाया जाएगा।

मूल रूप से finalLayoutAttributesForDisappearingItemAtIndexPath स्क्रीन पर प्रत्येक आइटम एनीमेशन ब्लॉक शुरू होने से पहले के लिए कहा जाता है, और initialLayoutAttributesForAppearingItemAtIndexPath एनीमेशन ब्लॉक समाप्त होने के बाद प्रत्येक आइटम के लिए कहा जाता है। prepareForCollectionViewUpdates में भेजे गए UICollectionViewUpdateItem ऑब्जेक्ट्स की सरणी को कैश करने के लिए आप पर निर्भर है ताकि आप प्रारंभिक और अंतिम विशेषताओं को कैसे सेट अप करें। मेरे मामले में मैंने prepareLayout में पिछले लेआउट आयतों को कैश किया था, इसलिए मुझे उपयोग करने के लिए सही प्रारंभिक स्थिति पता था।

एक चीज जो मुझे थोड़ी देर के लिए रुक गई है, आपको initialLayoutAttributesForAppearingItemAtIndexPath के सुपर के कार्यान्वयन का उपयोग करना चाहिए और इसके द्वारा लौटाए गए गुणों को संशोधित करना चाहिए। मैं अपने कार्यान्वयन में बस layoutAttributesForItemAtIndexPath पर फोन कर रहा था, और एनिमेशन काम नहीं कर रहे थे क्योंकि लेआउट की स्थिति अलग थी।

18

मुझे उपयोगी होने के लिए this blog post by Mark Pospesel मिला।
लेखक ने डब्ल्यूडब्ल्यूडीसी CircleLayout नमूना और posted it on Github भी तय किया। ब्याज की

तरीके:

- (void)prepareForCollectionViewUpdates:(NSArray *)updateItems 
{ 
    // Keep track of insert and delete index paths 
    [super prepareForCollectionViewUpdates:updateItems]; 

    self.deleteIndexPaths = [NSMutableArray array]; 
    self.insertIndexPaths = [NSMutableArray array]; 

    for (UICollectionViewUpdateItem *update in updateItems) 
    { 
     if (update.updateAction == UICollectionUpdateActionDelete) 
     { 
      [self.deleteIndexPaths addObject:update.indexPathBeforeUpdate]; 
     } 
     else if (update.updateAction == UICollectionUpdateActionInsert) 
     { 
      [self.insertIndexPaths addObject:update.indexPathAfterUpdate]; 
     } 
    } 
} 

- (void)finalizeCollectionViewUpdates 
{ 
    [super finalizeCollectionViewUpdates]; 
    // release the insert and delete index paths 
    self.deleteIndexPaths = nil; 
    self.insertIndexPaths = nil; 
} 

// Note: name of method changed 
// Also this gets called for all visible cells (not just the inserted ones) and 
// even gets called when deleting cells! 
- (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath 
{ 
    // Must call super 
    UICollectionViewLayoutAttributes *attributes = [super initialLayoutAttributesForAppearingItemAtIndexPath:itemIndexPath]; 

    if ([self.insertIndexPaths containsObject:itemIndexPath]) 
    { 
     // only change attributes on inserted cells 
     if (!attributes) 
      attributes = [self layoutAttributesForItemAtIndexPath:itemIndexPath]; 

     // Configure attributes ... 
     attributes.alpha = 0.0; 
     attributes.center = CGPointMake(_center.x, _center.y); 
    } 

    return attributes; 
} 

// Note: name of method changed 
// Also this gets called for all visible cells (not just the deleted ones) and 
// even gets called when inserting cells! 
- (UICollectionViewLayoutAttributes *)finalLayoutAttributesForDisappearingItemAtIndexPath:(NSIndexPath *)itemIndexPath 
{ 
    // So far, calling super hasn't been strictly necessary here, but leaving it in 
    // for good measure 
    UICollectionViewLayoutAttributes *attributes = [super finalLayoutAttributesForDisappearingItemAtIndexPath:itemIndexPath]; 

    if ([self.deleteIndexPaths containsObject:itemIndexPath]) 
    { 
     // only change attributes on deleted cells 
     if (!attributes) 
      attributes = [self layoutAttributesForItemAtIndexPath:itemIndexPath]; 

     // Configure attributes ... 
     attributes.alpha = 0.0; 
     attributes.center = CGPointMake(_center.x, _center.y); 
     attributes.transform3D = CATransform3DMakeScale(0.1, 0.1, 1.0); 
    } 

    return attributes; 
} 
0

आप UICollectionViewFlowLayout subclassed है, तो आप super कार्यान्वयन कॉल कर सकते हैं। एक बार जब आप डिफ़ॉल्ट प्रारंभिक लेआउट प्राप्त कर लेते हैं, तो आप 0 के .alpha की जांच कर सकते हैं। यदि alpha0 के अलावा कुछ भी है, तो सेल को स्थानांतरित किया जा रहा है, यदि यह 0 है तो इसे डाला जा रहा है।

एक हैक का बिट, मुझे पता है, लेकिन यह काम करता है।

स्विफ्ट 2.0 कार्यान्वयन इस प्रकार है:

override func initialLayoutAttributesForAppearingItemAtIndexPath(itemIndexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? { 


    guard let attributes = super.initialLayoutAttributesForAppearingItemAtIndexPath(itemIndexPath) where attributes.alpha == 0 else { 
     return nil 
    } 

    // modify attributes for insertion here 

    return attributes 

} 
0

सुनिश्चित करें कि आप स्विफ्ट 3. में नई विधि हस्ताक्षर का उपयोग कर रहे स्वचालितसुधार इस विधि के लिए काम नहीं करता है बनाओ:

func initialLayoutAttributesForAppearingItem(at itemIndexPath: IndexPath) -> UICollectionViewLayoutAttributes?