4

短い質問:

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

長い説明:

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

それを達成するために、次の実装でカスタムUICollectionViewFlowLayoutベースのレイアウトを実装しました。prepareLayout:

- (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];
                }
            }
        }
    }
}

すべてのデータが最初から利用可能で、データに変更がない場合、これはうまく機能します。ただし、存続期間中にデータが追加および削除されると、惨めに失敗します。セルの挿入と削除によりperformBatchUpdates:、補足ビューが台無しになります。

何が起こるべきか:

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

問題:

私のprepareLayout:レイアウトの が呼び出され、正しい が計算されますlayoutAttributes。しかしlayoutAttributesForSupplementaryViewOfKind:atIndexPath:、奇妙なために呼び出されindexPathsます。具体的には、配列から削除されたlayoutAttributesForSupplementaryViewOfKind:atIndexPath:old に対して が呼び出されます!indexPathssupplementaryViewAttributeList

例:

新しいセルが挿入された場合、 はprepareLayout:を正しく削除しますlayoutAttributesが、layoutAttributesForSupplementaryViewOfKind:atIndexPath: 使用できなくなって削除された indexPath に対して が呼び出されます。そしてそのためだけに。indexPath他のすべての補足ビューについて、他の s に対する追加の呼び出しはありません。

なぜそれが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:クラスの最後のメソッドにあります)

4

2 に答える 2

3

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

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

そして物事はかなりうまくいかないことがあります。

于 2016-07-10T07:51:36.883 に答える