3

短い質問:どうUICollectionViewできる補助的な見解は、挿入または正しく削除さ

insertItemsAtIndexPaths:deleteItemsAtIndexPaths:あるいはreloadItemsAtIndexPaths:方法と同様のperformBatchUpdates:ブロック内のセルやセクションなどの補助的なビューを追加し、削除する方法はありますか?

ロング説明:

私はセクションでUICollectionViewを使用しています。セルはグリッドのように配置され、各行に最大6つのセルを配置できます。セルの総量がセクションのすべての行をいっぱいにしない場合は、追加のビューを追加します。付加的な補足的なビューは空のスペースを埋めるだけです。その結果、各セクションはすべての利用可能なセルで完全に埋められ、(可能な)残りの空のスポットは補助ビューで満たされます。各行には6つの視覚的要素があり、セルまたは補足的な視点があります。

- (void)prepareLayout { 
    [super prepareLayout]; 

    self.supplementaryViewAttributeList = [NSMutableArray array]; 
    if(self.collectionView != nil) { 
     // calculate layout values 
     CGFloat contentWidth = self.collectionViewContentSize.width - self.sectionInset.left - self.sectionInset.right; 
     CGFloat cellSizeWithSpacing = self.itemSize.width + self.minimumInteritemSpacing; 
     NSInteger numberOfItemsPerLine = floor(contentWidth/cellSizeWithSpacing); 
     CGFloat realInterItemSpacing = (contentWidth - (numberOfItemsPerLine * self.itemSize.width))/(numberOfItemsPerLine - 1); 

     // add supplementary attributes 
     for (NSInteger numberOfSection = 0; numberOfSection < self.collectionView.numberOfSections; numberOfSection++) { 
      NSInteger numberOfItems = [self.collectionView numberOfItemsInSection:numberOfSection]; 
      NSInteger numberOfSupplementaryViews = numberOfItemsPerLine - (numberOfItems % numberOfItemsPerLine); 

      if (numberOfSupplementaryViews > 0 && numberOfSupplementaryViews < 6) { 
       NSIndexPath *indexPathOfLastCellOfSection = [NSIndexPath indexPathForItem:(numberOfItems - 1) inSection:numberOfSection]; 
       UICollectionViewLayoutAttributes *layoutAttributesOfLastCellOfSection = [self layoutAttributesForItemAtIndexPath:indexPathOfLastCellOfSection]; 

       for (NSInteger numberOfSupplementor = 0; numberOfSupplementor < numberOfSupplementaryViews; numberOfSupplementor++) { 
        NSIndexPath *indexPathOfSupplementor = [NSIndexPath indexPathForItem:(numberOfItems + numberOfSupplementor) inSection:numberOfSection]; 
        UICollectionViewLayoutAttributes *supplementaryLayoutAttributes = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:ARNCollectionElementKindFocusGuide withIndexPath:indexPathOfSupplementor]; 
        supplementaryLayoutAttributes.frame = CGRectMake(layoutAttributesOfLastCellOfSection.frame.origin.x + ((numberOfSupplementor + 1) * (self.itemSize.width + realInterItemSpacing)), layoutAttributesOfLastCellOfSection.frame.origin.y, self.itemSize.width, self.itemSize.height); 
        supplementaryLayoutAttributes.zIndex = -1; 

        [self.supplementaryViewAttributeList addObject:supplementaryLayoutAttributes]; 
       } 
      } 
     } 
    } 
} 

すべてのデータが最初から利用可能な場合、データに変更がない場合、これは素晴らしい作品:私は、次のprepareLayout:実装してカスタムUICollectionViewFlowLayoutベースのレイアウトを実装することを達成するために

。しかし、生涯にデータが追加されたり削除されたりすると、悲惨な結果に終わります。 performBatchUpdates:のセルの挿入と削除は補助ビューを混乱させます。

何が起こる必要があります。同じindexPathで補足ビューを削除する必要がありますinsertItemsAtIndexPaths:に挿入されているすべてのセルについては

。さらに、deleteItemsAtIndexPaths:で削除されたすべてのセルに対して、新しい補助ビューを同じindexPathに追加する必要があります。

問題:私のレイアウトの

prepareLayout:が呼び出され、正しいlayoutAttributesが算出されます。しかし、layoutAttributesForSupplementaryViewOfKind:atIndexPath:は奇妙なindexPathsのために呼び出されます。特にlayoutAttributesForSupplementaryViewOfKind:atIndexPath:supplementaryViewAttributeList配列から削除された古いindexPathsを呼び出されます。

例:新しいセルが挿入されます場合は

prepareLayout:が正しくlayoutAttributesを削除しますが、layoutAttributesForSupplementaryViewOfKind:atIndexPath:はまだありませんもう利用を呼びかけやindexPathを削除されます!そして、それだけです。他のすべての補足ビューについては、その他の追加の呼び出しはありません。

なぜlayoutAttributesForSupplementaryViewOfKind:atIndexPath:indexPathsと呼ばれていますか?補助ビューを正しく削除、挿入、または再ロードするにはどうすればよいですか?何が欠けていますか?

出典:完全なソースはここで見つけることができ

カスタムレイアウト:https://github.com/sarn/ARNClassicFilms/blob/master/classicFilms/classicFilms/layout/ARNCollectionViewFocusGuideFlowLayout.m

CollectionViewコントローラー: https://github.com/sarn/ARNClassicFilms/blob/master/classicFilms/classicFilms/view-controllers/ARNMovieOverviewController.m

performBatchUpdates:は、クラスの最後のメソッドです)
+0

ちょっと私はあなたのポストに起こって、あなたが何かを見つけたのかしら?実際に私は先週WWDCでアップルエンジニアに尋ねた。[非常に似た問題](http://stackoverflow.com/questions/38005641/no-uicollectionviewlayoutattributes-instance-for-layoutattributesforsupplementa/38005845#38005845) – Genhain

+1

彼が提供した解決策は、 '[[collectionView collectionViewLayout] invalidateLayout];'を 'performBatchUpdates:'ブロックに追加することでした。これは実際に私の場合に有効です。たぶんこれはあなたのケースでも助けてくれるでしょう –

+0

私は近くにあったので、ブロックの直前に追加しました。 – Genhain

答えて

1

1つの解決策は、[[collectionView collectionViewLayout] invalidateLayout]を追加することですe performBatchUpdates:ブロック。これにより、レイアウトは強制的に無効なindexPathを再計算して削除します。

2

あなたのコメントは私のトリックではありませんでした。別のコードを見つけて追加しました。それはうまく機能し、上記の提案を削除しても機能しました。コレクションビューは確かに強力ですが、このような1つの機能を忘れてしまいます...

- (NSArray<NSIndexPath *> *)indexPathsToDeleteForSupplementaryViewOfKind:(NSString *)elementKind 
{ 
    return self.removedIndexPaths; 
} 

そして事はかなりうまくいく可能性があります。

関連する問題