14

我正在寫一個自定義的UICollectionViewFlowLayout和我注意到,initialLayoutAttributesForAppearingItemAtIndexPath:initialLayoutAttributesForAppearingDecorationElementOfKind:atIndexPath:將被用於所有的部分,當我在集合視圖調用performBatchUpdates:completion:。結果是全部段都有應用到它們的動畫而不是只是的新增段落。UICollectionView performBatchUpdates:動畫所有部分

[collectionView performBatchUpdates:^{ 
    currentModelArrayIndex++; 
    [collectionView insertSections:[NSIndexSet indexSetWithIndex:currentModelArrayIndex]]; 
    [collectionView reloadSections:[NSIndexSet indexSetWithIndex:currentModelArrayIndex-1]]; 
} completion:^(BOOL finished) { 
    [collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:currentModelArrayIndex] atScrollPosition:UICollectionViewScrollPositionTop animated:YES]; 
}]; 

什麼我試過到目前爲止以代替簡單的更新移除調用performBatchUpdates:completion:,但已有部分(全部)在動畫反正。我想出了一個檢查的解決方案,以確保我改變的佈局屬性最後一部分,但它感覺哈克。

if (decorationIndexPath.section == [(id<UICollectionViewDataSource>)self.collectionView.delegate numberOfSectionsInCollectionView:self.collectionView] - 1) 
{ 
    layoutAttributes.alpha = 0.0f; 
    layoutAttributes.transform3D = CATransform3DMakeTranslation(-CGRectGetWidth(layoutAttributes.frame), 0, 0); 
} 

這是適當的方式去動畫只有一些部分?

回答

7

好的,我有一個答案;它並沒有比前一個更漂亮,但它使佈局不會觸及數據源,因此它更乾淨。

基本上,我們需要覆蓋prepareForCollectionViewUpdates:finalizeCollectionViewUpdates以跟蹤我們插入的部分。我有一個可變集合,其中包含我們要插入的部分的NSNumber實例。

-(void)prepareForCollectionViewUpdates:(NSArray *)updateItems 
{ 
    [super prepareForCollectionViewUpdates:updateItems]; 

    [updateItems enumerateObjectsUsingBlock:^(UICollectionViewUpdateItem *updateItem, NSUInteger idx, BOOL *stop) { 
     if (updateItem.updateAction == UICollectionUpdateActionInsert) 
     { 
      [insertedSectionSet addObject:@(updateItem.indexPathAfterUpdate.section)]; 
     } 
    }]; 
} 

-(void)finalizeCollectionViewUpdates 
{ 
    [super finalizeCollectionViewUpdates]; 

    [insertedSectionSet removeAllObjects]; 
} 

接下來,我檢查在設置項目和裝飾視圖的初始佈局屬性時是否包含該索引路徑的部分。

-(UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingDecorationElementOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)decorationIndexPath 
{ 
    UICollectionViewLayoutAttributes *layoutAttributes; 

    if ([elementKind isEqualToString:AFCollectionViewFlowLayoutBackgroundDecoration]) 
    { 
     if ([insertedSectionSet containsObject:@(decorationIndexPath.section)]) 
     { 
      layoutAttributes = [self layoutAttributesForDecorationViewOfKind:elementKind atIndexPath:decorationIndexPath]; 
      layoutAttributes.alpha = 0.0f; 
      layoutAttributes.transform3D = CATransform3DMakeTranslation(-CGRectGetWidth(layoutAttributes.frame), 0, 0); 
     } 
    } 

    return layoutAttributes; 
} 

-(UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath 
{ 
    UICollectionViewLayoutAttributes *layoutAttributes; 

    if ([insertedSectionSet containsObject:@(itemIndexPath.section)]) 
    { 
     layoutAttributes = [self layoutAttributesForItemAtIndexPath:itemIndexPath]; 
     layoutAttributes.transform3D = CATransform3DMakeTranslation([self collectionViewContentSize].width, 0, 0); 
    } 

    return layoutAttributes; 
} 

我要回的這些方法,否則nil因爲nil是默認值。

這還有更好的旋轉動畫的附加好處。

相關問題