如何在更改集合视图单元的大小时为其设置内部视图的动画?

时间:2013-11-22 03:41:38

标签: ios autolayout

我有一个集合视图,我正在寻找一个效果,当一个单元被点击时,它会逐渐占据整个屏幕。为实现此目的,我基本上只是在performBatchUpdates内调用didSelectItemAtIndexPathsizeForItemAtIndexPath知道为所选单元格返回更大的尺寸。这一切都很有效,细胞会根据需要增长和缩小。

问题出在细胞内部。集合视图单元由由约束管理的中等复杂视图层次结构组成。我希望细胞的子视图随着动画细胞的增长而缩小。不幸的是,我的子视图会立即捕捉到他们的新位置,因为单元格会逐渐变为新的大小。如何确保单元格内容与单元格大小相同?

以下是集合视图控制器中的两个相关方法:

- (CGSize) collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
if ([collectionView.indexPathsForSelectedItems containsObject:indexPath])
    return CGSizeMake(collectionView.bounds.size.width - 20, collectionView.bounds.size.height - (20 + [self.topLayoutGuide length]));
else
    return CGSizeMake(260, 100); 
}

- (void) collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
    [collectionView performBatchUpdates:nil completion:nil];
}

3 个答案:

答案 0 :(得分:11)

我有完全相同的问题。经过多次尝试,以下代码为我做了诀窍。在批量更新后直接调用layoutIfNeed,持续时间为3.0(+ - batchupdate duration),为约束设置动画。

[self performBatchUpdates:nil completion:nil];

// IndexPath of cell to be expanded
UICollectionViewCell *cell = [self cellForItemAtIndexPath:indexPath];
[UIView animateWithDuration:0.3 animations:^{
    [cell.contentView layoutIfNeeded];
}];

答案 1 :(得分:2)

我想扩展Antoine的答案。在动画块内调用performBatchUpdates:completion:实际上将设置单元格调整大小持续时间并将内容调整大小与其匹配。

[UIView animateWithDuration:0.3 animations:^{
    [self performBatchUpdates:^{
        // set flags needed for new cell size calculation
    } completion:nil];
    [collectionView layoutIfNeeded];
}];

通过这种方式,您还可以播放动画时序,甚至可以使用弹簧动画。

答案 2 :(得分:0)

我有同样的问题。将这些添加到CollectionViewCell的子类中。它对我有用。

// ProblematicCollectionViewCell.swift

override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) {
    super.apply(layoutAttributes)
   layoutIfNeeded()
}

以下是origanl链接:https://codedump.io/share/LXZwAOOMxafU/1/uicollectionviewcell---contents-do-not-animate-alongside-cell39s-contentview答案在评论中。