[英]UICollectionView contentOffset changes with custom layout
[英]Animating contentOffset changes in a UICollectionView on deleteItemsAtIndexPaths
我有一个UICollectionView
,可以添加和删除单元格。 我正在使用performBatchUpdates
进行这些更改,并且布局按预期动画。
当我滚动到内容的末尾并删除一个项目以使contentSize
减少时,会出现问题:这会导致contentOffset
更改,但更改不会设置动画。 相反, contentOffset
在删除动画完成后立即跳转。 我已尝试手动更新contentOffset
以及删除,但这对我也不起作用。
我正在使用自定义布局,但我使用以下代码看到标准流布局的相同行为:
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return self.items.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
UILabel *label = (UILabel *)[cell viewWithTag:1];
label.text = [self.items objectAtIndex:indexPath.item];
return cell;
}
- (IBAction)addItem:(UIBarButtonItem *)sender
{
self.runningCount++;
[self.items addObject:[NSString stringWithFormat:@"Item %u",self.runningCount]];
[self.collectionView performBatchUpdates:^{
[self.collectionView insertItemsAtIndexPaths:@[[NSIndexPath indexPathForItem:self.items.count-1 inSection:0]]];
} completion:nil];
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
[self.items removeObjectAtIndex:indexPath.item];
[self.collectionView performBatchUpdates:^{
[self.collectionView deleteItemsAtIndexPaths:@[indexPath]];
} completion:nil];
}
我觉得我必须错过一些明显的东西,但这让我很难过。
可以看到动画故障,其中集合视图的contentSize
缩小,使得其高度或宽度变得小于(或等于)集合视图边界的高度或宽度。
可以使用setContentOffset:animated:
和类似的方法强制批量更新块中的预期动画,但这取决于在删除后知道预计的内容大小。 内容大小由集合视图布局管理,但由于我们还没有实际删除单元格,我们不能只询问布局(或者我们得到旧的大小)。
为了解决这个问题,我在自定义布局中实现了targetContentOffsetForProposedContentOffset:
方法,以根据需要调整内容偏移量。 以下代码仅代表Y偏移量,足以满足我的需求:
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset
{
if (self.collectionViewContentSize.height <= self.collectionView.bounds.size.height)
{
return CGPointMake(proposedContentOffset.x,0);
}
return proposedContentOffset;
}
我在直接的UICollectionViewFlowLayout子类中尝试了这个,它也在那里完成了工作。
从问题讨论中引用,这对我很有用
[self.dataArray removeObjectAtIndex:index];
[self.collectionView deleteItemsAtIndexPaths:@[[NSIndexPath indexPathForItem:index inSection:0]]];
[self.collectionView performBatchUpdates:^{
[self.collectionView reloadData];
} completion:nil];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.