首页 文章

UICollectionView动画数据更改

提问于
浏览
76

在我的项目中,我使用UICollectionView来显示图标网格 .

用户可以通过单击分段控件来更改排序,该分段控件使用不同的NSSortDescriptor调用从核心数据中获取 .

The amount of data is always the same, just ending up in different sections / rows:

- (IBAction)sortSegmentedControlChanged:(id)sender {

   _fetchedResultsController = nil;
   _fetchedResultsController = [self newFetchResultsControllerForSort];

   NSError *error;
   if (![self.fetchedResultsController performFetch:&error]) {
       NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
   }

   [self.collectionView reloadData];
}

问题是reloadData没有为更改设置动画,UICollectionView只是弹出新数据 .

我应该跟踪更改前后单元格中的哪个indexPath,并使用[self.collectionView moveItemAtIndexPath:toIndexPath:]来执行更改动画,还是有更好的方法?

我没有太多进入子类化collectionViews所以任何帮助将是伟大的...

比尔,谢谢 .

8 回答

  • 59

    reloadData不会设置动画,也不会在放入UIView动画块时可靠地执行此操作 . 它想要在UICollecitonView performBatchUpdates块中,所以尝试更像:

    [self.collectionView performBatchUpdates:^{
        [self.collectionView reloadSections[NSIndexSet indexSetWithIndex:0]];
    } completion:^(BOOL finished) {}];
    
  • 1

    -performBatchUpdates: 中包装 -reloadData 似乎不会导致单节集合视图进行动画处理 .

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

    但是,此代码有效:

    [self.collectionView performBatchUpdates:^{
        [self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];
    } completion:nil];
    
  • 2

    这就是我为动画重新加载ALL SECTIONS所做的工作:

    [self.collectionView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, self.collectionView.numberOfSections)]];
    

    Swift 3

    let range = Range(uncheckedBounds: (0, collectionView.numberOfSections))
    let indexSet = IndexSet(integersIn: range)
    collectionView.reloadSections(indexSet)
    
  • -4

    对于Swift用户,如果您的collectionview只有一个部分:

    self.collectionView.performBatchUpdates({
                        let indexSet = IndexSet(integersIn: 0...0)
                        self.collectionView.reloadSections(indexSet)
                    }, completion: nil)
    

    正如https://stackoverflow.com/a/42001389/4455570所见

  • 65

    如果您想要更多控件和可自定义功能检查this,它包含对UICollectionViewCell动画的各种方式的非常详细的解释 .

  • 2

    重新加载 performBatchUpdates:completion: 块内的整个集合视图在iOS 9模拟器上为我做了一个小故障动画 . 如果您想要删除特定的 UICollectionViewCell ,或者如果您有索引路径,则可以在该块中调用 deleteItemsAtIndexPaths: . 通过使用 deleteItemsAtIndexPaths: ,它可以做出流畅而漂亮的动画 .

    UICollectionViewCell* cellToDelete = /* ... */;
    NSIndexPath* indexPathToDelete = /* ... */;
    
    [self.collectionView performBatchUpdates:^{
        [self.collectionView deleteItemsAtIndexPaths:@[[self.collectionView indexPathForCell:cell]]];
        // or...
        [self.collectionView deleteItemsAtIndexPaths:@[indexPath]];
    } completion:nil];
    
  • 4

    帮助文字说:

    调用此方法重新加载集合视图中的所有项目 . 这会导致集合视图丢弃任何当前可见的项目并重新显示它们 . 为了提高效率,集合视图仅显示可见的单元格和补充视图 . 如果集合数据由于重新加载而缩小,则集合视图会相应地调整其滚动偏移 . 不应在插入或删除项目的动画块中间调用此方法 . 插入和删除会自动使表的数据得到适当更新 .

    我认为关键部分是“使集合视图丢弃任何当前可见的项目” . 如何动画它丢弃的物品的动作?

  • 143

    对于快速用户来说,这很方便 -

    collectionView.performBatchUpdates({ 
    
                self.collectionView.reloadSections(NSIndexSet(index: index))
    
                }, completion: nil)
    

相关问题