8

है, मेरे पास एक सामान्य UICollectionView है जो UICollectionViewFlowLayout को लंबवत फैशन में उपयोग कर रहा है। मैं संग्रह दृश्य को पॉप्युलेट करने के लिए पेजिनेशन के साथ एक बाकी एपीआई का उपयोग कर रहा हूं। जब मैं मैं चलानेUICollectionView अनुभाग में डालने वाले मुद्दे जिनमें एक पाद लेख

-(void)loadNextPageOfAssets{ 
    __weak RDRadiusGridViewController *weakSelf = self; 

    // Increment page and request assets. They are added to cluster.assets before the completion block is called. 
    self.cluster.pagination.page++; 
    [self.cluster requestAssetsWithCompletionBlock:^(NSArray *assets) { 

     SM_LOG_DEBUG(@"page.total: %ld assets.count: %ld", self.cluster.pagination.totalCount, (long)assets.count); 

     NSMutableArray *indexPaths = [[NSMutableArray alloc]initWithCapacity:assets.count]; 
     for(NSUInteger index = 0; index < assets.count; index++){ 
      NSIndexPath *indexPath = [NSIndexPath indexPathForItem:self.cluster.assets.count - assets.count + index inSection:0]; 
      SM_LOG_DEBUG(@"Inserting indexPath: %ld:%ld", (long)indexPath.item, (long)indexPath.section); 
      [indexPaths addObject:indexPath]; 
     } 
     [weakSelf.collectionView performBatchUpdates:^{ 
      [weakSelf.collectionView insertItemsAtIndexPaths:indexPaths]; 
     } completion:^(BOOL finished) { 

     }]; 

//   [weakSelf.collectionView reloadData]; 
    }]; 
} 

: आदेश डाउनलोड करने के लिए अगले पृष्ठ को गति प्रदान करने में, मैं प्रतिनिधि उपयोग कर रहा हूँ जब यह पाद लेख लेआउट के लिए पूछता है:

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath{ 
    RDLoadMoreReusableView *view = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"RDLoadMoreReusableView" forIndexPath:indexPath]; 
    view.delegate = self; 
    [view start]; 
    [self loadNextPageOfAssets]; 
    return view; 
} 

यहाँ मेरी loadNextPageOfAssets पीछे कोड है मेरे व्यू कंट्रोलर पर जा सकते हैं और लोड की गई संपत्तियों का पहला पृष्ठ देख सकते हैं। अगर मैं नीचे स्क्रॉल मैं पाद लेख दृश्य (जो एक स्पिनर शामिल हैं) देखेंगे, लेकिन उसके बाद कोड लाइन में अपवाद को तोड़ने बिंदु पर टूट जाएगा:

[weakSelf.collectionView insertItemsAtIndexPaths:indexPaths]; 

अभिकथन विफलता में - [UICollectionViewData layoutAttributesForSupplementaryElementOfKind: atIndexPath:] , /SourceCache/UIKit/UIKit-3185.20/UICollectionViewData.m:829


फिर अगर मैं जारी रखने के लिए यह त्रुटि के साथ दुर्घटनाओं:

2014-06-11 16: 39: 58.335 त्रिज्या-iOS [ 4 9 01: 525006] * ऐप को समाप्त करना न आया हुआ अपवाद 'NSInternalInconsistencyException', कारण: '-layoutAttributesForSupplementaryElementOfKind के लिए कोई UICollectionViewLayoutAttributes उदाहरण: पथ पर UICollectionElementKindSectionFooter {लंबाई = 2, पथ = 0 - 0}' * पहले फेंक कॉल स्टैक:


यह puzzling है मुझे। layoutAttributesForSupplementaryElementOfKind लगता है कि यह लेआउट क्लास के साथ करने के लिए कुछ है, लेकिन मैं एक कस्टम प्रवाह लेआउट का उपयोग नहीं कर रहा बल्कि डिफ़ॉल्ट आपूर्ति की जा रहा हूं। ऐसा लगता है जैसे ऐप्पल का कोड पागल है लेकिन मुझे लगता है कि मैं सब कुछ ठीक से उपयोग कर रहा हूं।

[self loadNextPageOfAssets]; 

अनुपूरक सेल विपंक्ति से UICollectionViewCell Deque तेह के लिए, और सभी को एक साथ पाद लेख दृश्य हटाने के लिए, तो डालने महान काम करता है:

अब अगर मैं कॉल चलते हैं।

अभी के लिए मैं सम्मिलित करने के बजाय reloadData को कॉल कर रहा हूं, लेकिन यह UGLY है।

क्या मैं पाद लेखों के बारे में कुछ देख रहा हूं?

+0

wel .. शुरुआत आप जांच कर सकता है पूरक तत्व तरह कि viewForSupplementaryElementOfKind में पारित हो जाता – govi

उत्तर

8

वापरवेयरवॉल्फ द्वारा प्रदान किया गया उत्तर एक हैक का थोड़ा सा है। शून्य आकार के बजाय एक छोटे आकार को लौटकर, पूरक दृश्य हमेशा मौजूद रहेगा लेकिन देखने के लिए आकार में बहुत छोटा होगा। तो यही कारण है कि यह NSInternalInconsistencyException

ठीक करता है लेकिन, यहां वास्तविक समाधान है।

डेटा स्रोत के लिए डेटा जोड़ने के बाद और insertItemsAtIndexPaths कॉल करने से पहले, बस इसे परिवर्तन के बारे में पता करने के लिए collectionview पर लेआउट अमान्य हो जाएगा।

ऑब्जेक्टिव-सी

[self.collectionView.collectionViewLayout invalidateLayout] 

स्विफ्ट

collectionView.collectionViewLayout.invalidateLayout() 
+0

मैं आपसे सहमत हूं। मैंने यूआईसीओलेक्शन व्यू के बारे में बहुत कुछ सीखा है क्योंकि मैंने इस पोस्ट को साल पहले बनाया था। इसे स्वीकृत उत्तर में बदलना। – VaporwareWolf

+0

महान उत्तर के लिए धन्यवाद। मेरे द्वारा भी यही समस्या का सामना किया जा रहा है। डिफ़ॉल्ट स्रोत लेआउट का उपयोग करना और डेटा स्रोत खाली होने पर मेरे पाद लेख के लिए CGSizeZero लौटाएं। यदि ऐप डालने या मूविंग करने से पहले मैं अमान्यता को कॉल नहीं करता हूं तो ऐप क्रैश हो जाएगा – PrimaryChicken

0

रूसी में यूआईसीओलेक्शन व्यू में बग के बारे में एक बड़ा लेख है: http://habrahabr.ru/post/211144/

@try { 
    [self.collectionView insertItemsAtIndexPaths:indexPaths]; 
} 
@catch (NSException *exception) {} 

या

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

आप दोनों (शीर्ष लेख और पाद) तरीकों को लागू करना चाहिए:

यहाँ कि आपकी समस्या का समाधान हो सकता है कि लेख से तरीकों में से एक जोड़े हैं। भले ही आप केवल एक चाहते हैं।मेरी कोड

-(UICollectionReusableView *) collectionView:(UICollectionView *) collectionView 
      viewForSupplementaryElementOfKind:(NSString *) kind 
           atIndexPath:(NSIndexPath *) indexPath 
{ 
    UICollectionReusableView *header = [[UICollectionReusableView alloc] init]; 

    if ([kind isEqualToString:UICollectionElementKindSectionHeader]) { 

     header = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"CollectionViewHeader" forIndexPath:indexPath]; 
    } 
    else { 
     header = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"CollectionViewHeader" forIndexPath:indexPath]; 
    } 

    return header; 
} 

-(CGSize) collectionView:(UICollectionView *) collectionView 
         layout:(UICollectionViewLayout *) collectionViewLayout 
referenceSizeForHeaderInSection:(NSInteger) section 
{ 
    return CGSizeMake(self.view.frame.size.width, 100); 
} 

-(CGSize) collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section { 
    return CGSizeZero; 
} 
8

को देखो ऐसा लगता है कि मैं वास्तव में लेआउट के साथ एक समस्या का सामना कर रहा था (के रूप में त्रुटि विवरण से पता चलता है)

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section{ 
    if(<myDecision>){ 
     return CGSizeZero; 
    } else { 
     return CGSizeMake(320, 50); 
    } 
} 

CGSizeZero क्रैश पैदा कर रहा था है। इसके बजाय CGSizeMake (0.001, 0.001) का उपयोग करें। यही एकमात्र बदलाव है जो आवश्यक था। यह अब इरादे के रूप में चलाता है।

+1

इस के लिए धन्यवाद है क्या! कोई कारण क्यों कोई CGGizeZero वापस नहीं कर सकता है? संग्रह दृश्य के टैंट्रम्स को संभालना बेहद परेशान है :( – akdsouza

+0

जो कि बहुत निराशाजनक था लेकिन इसने इसे धन्यवाद दिया! :) – agandi

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