1

我有一個UICollectionView,其內容由NSFetchedResultsController提供。每當更新核心數據時,都會通過reloadItemsAtIndexPaths:方法調用集合視圖中的已更改項目。未在CoreData上調用UICollectionView DataSource方法更改

經過大量測試後,我確定上述過程正常工作。我對核心數據進行更新,最終調用數據源方法「cellForItemAtIndexPath」,並按預期更新單元。但是,我還實現了數據源方法'viewForSupplementaryElementOfKind',以顯示一些單元格標題(也基於對核心數據的更改),並且這不正常工作。

出於某種原因,似乎當「reloadItemsAtIndexPaths」核心數據的變化之後被調用,「viewForSupplementaryElementOfKind」不會被調用,我想不通爲什麼會出現這種情況。但是,一旦我開始滾動收集視圖,則會調用 'viewForSupplementaryElementOfKind',並且我可以像我期望的那樣根據核心數據更改在補充標題視圖中看到更新。在初始創建UICollectionView時,該方法也會成功調用。

我有一個自定義佈局,我正在使用我的集合視圖,所以也許問題出在那裏?我希望有人能夠發現我的錯誤。

下面是用於創建UICollectionView,其佈局,細胞及其首部視圖的代碼:

  1. 創建UICollectionView

     - (void)createCollectionView 
         { 
          _layout1 = [[BigLayout alloc] init]; //custom layout 
          [_layout1 setScrollDirection:UICollectionViewScrollDirectionHorizontal]; 
    
          _collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:_layout1]; 
          _collectionView.translatesAutoresizingMaskIntoConstraints = NO; 
          _collectionView.backgroundColor = [UIColor clearColor]; 
    
          _collectionView.dataSource = self; 
          _collectionView.delegate = self; 
    
          [self.view addSubview:_collectionView]; 
    
          //set up constraints, add them to view... 
    
          [self.collectionView registerClass:[InboxCell class] 
            forCellWithReuseIdentifier:@"inbox"]; 
          [self.collectionView registerClass:[UICollectionReusableView class] 
            forSupplementaryViewOfKind:UICollectionElementKindSectionHeader 
              withReuseIdentifier:@"header"]; 
         } 
    
  2. 創建自定義佈局

    @implementation BigLayout 
    
        -(id)init 
        { 
         self = [super init]; 
         if (self) { 
          self.itemSize = CGSizeMake(330, 588); 
          self.scrollDirection = UICollectionViewScrollDirectionHorizontal; 
          self.headerReferenceSize = CGSizeMake(13, 13); 
         } 
         return self; 
        } 
    
        -(void)prepareLayout 
        { 
         [super prepareLayout]; 
    
         _cellCount = [[self collectionView] numberOfItemsInSection:0]; 
        } 
    
        - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)path 
        { 
         UICollectionViewLayoutAttributes* attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:path]; 
         attributes.size = self.itemSize; 
         attributes.center = CGPointMake(path.item * (self.itemSize.width + 20) + self.itemSize.width/2.0 + 20, self.collectionView.center.y); 
         return attributes; 
        } 
    
        - (CGSize)collectionViewContentSize 
        { 
         return CGSizeMake(((self.itemSize.width + 20) * _cellCount) + 80, [self collectionView].height); 
        } 
    
        -(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect 
        { 
         NSMutableArray* attributes = [NSMutableArray array]; 
         for (NSInteger i=0 ; i < self.cellCount; i++) { 
          NSIndexPath* indexPath = [NSIndexPath indexPathForItem:i inSection:0]; 
    
          UICollectionViewLayoutAttributes *attr = [self layoutAttributesForItemAtIndexPath:indexPath]; 
          UICollectionViewLayoutAttributes *hattr = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:indexPath]; 
    
          if (CGRectIntersectsRect(attr.frame, rect)) { 
           [attributes addObject:attr]; 
           [attributes addObject:hattr]; 
          } 
         } 
         return attributes; 
        } 
    
        - (void)prepareForCollectionViewUpdates:(NSArray *)updateItems 
        { 
    
        } 
    
        - (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath 
        { 
         UICollectionViewLayoutAttributes* attributes = [self layoutAttributesForItemAtIndexPath:itemIndexPath]; 
         attributes.alpha = 1.0; 
         return attributes; 
        } 
    
        - (UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath 
        { 
         UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader withIndexPath:indexPath]; 
         attributes.size = CGSizeMake(13, 13); 
         attributes.center = CGPointMake(indexPath.item * (self.itemSize.width + 20) + self.itemSize.width/2.0 + 20 + self.collectionView.left, self.collectionView.height == 768 ? 75 : 200); 
         attributes.alpha = 1.0f; 
         return attributes; 
        } 
    
  3. 用於單元格的數據源方法(在CD更新中調用)

     - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 
         { 
          //this method gets called on reload items 
          InboxCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"inbox" forIndexPath:indexPath]; 
          Email *email = [self.fetchedResultsController objectAtIndexPath:indexPath]; 
          //do stuff with the email in the cell 
          return cell; 
         } 
    
  4. 數據源方法補充標題視圖(不叫上CD更新)

     - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView 
            viewForSupplementaryElementOfKind:(NSString *)kind 
                 atIndexPath:(NSIndexPath *)indexPath 
         { 
          //this method does not get called on reload items, only gets called initially and on scroll 
          UICollectionReusableView *reusableView; 
    
          if (kind == UICollectionElementKindSectionHeader) { //specify in case we add a footer later 
    
           UICollectionReusableView *unreadEmailImageIdentifier = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"header" forIndexPath:indexPath]; 
           Email *email = [self.fetchedResultsController objectAtIndexPath:indexPath]; 
           UIImageView *unreadEmailDot = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"dot.png"]]; 
           [unreadEmailImageIdentifier addSubview:unreadEmailDot]; 
           unreadEmailImageIdentifier.hidden = YES; 
    
           if (email.isUnread == YES || email.isUnread == 1) { 
            unreadEmailImageIdentifier.hidden = NO; 
           } 
           reusableView = unreadEmailImageIdentifier; 
          } 
    
          return reusableView; 
         } 
    

總之,看來,當我嘗試重新加載的集合視圖或組件集合視圖,補充標題視圖的數據源方法不會被調用。但是,我確實看到了在自定義佈局類IS中爲補充視圖創建屬性的方法。如果有人能指出任何可能的原因,這可能是 發生,我將不勝感激!

回答

0

reloadItemsAtIndexPaths僅用於重新加載單元格。您可以通過使用reloadSections:重新加載部分來重新加載補充視圖。如果您仍然遇到問題,請將您的問題納入NSFetchedResultsControllerDelegate實施中。

+0

就是這樣。 ReloadSections的作品。謝謝!! – jac300

相關問題