根据苹果公司的文档(并在2012年WWDC大会上被吹捧),可以动态地将布局设置为UICollectionView
,甚至可以将更改设置为动画:
通常在创建集合视图时指定布局对象,但也可以动态更改集合视图的布局.Layout对象存储在集合ViewLayout属性中.设置此属性会立即直接更新布局,而不会设置更改动画.如果要为更改设置动画,则必须改为调用setCollectionViewLayout:Animated:方法.
然而,在实践中,我发现UICollectionView
对contentOffset
做出了令人费解甚至无效的更改,导致细胞移动不正确,使得该功能实际上无法使用.为了说明这个问题,我将以下示例代码组合在一起,这些代码可以附加到拖放到情节提要中的默认集合视图控制器上:
#import <UIKit/UIKit.h>
@interface MyCollectionViewController : UICollectionViewController
@end
@implementation MyCollectionViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"CELL"];
self.collectionView.collectionViewLayout = [[UICollectionViewFlowLayout alloc] init];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 1;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:@"CELL" forIndexPath:indexPath];
cell.backgroundColor = [UIColor whiteColor];
return cell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"contentOffset=(%f, %f)", self.collectionView.contentOffset.x, self.collectionView.contentOffset.y);
[self.collectionView setCollectionViewLayout:[[UICollectionViewFlowLayout alloc] init] animated:YES];
NSLog(@"contentOffset=(%f, %f)", self.collectionView.contentOffset.x, self.collectionView.contentOffset.y);
}
@end
控制器在viewDidLoad
中设置默认值UICollectionViewFlowLayout
,并在屏幕上显示单个单元格.当单元格被选中时,控制器创建另一个默认值UICollectionViewFlowLayout
,并在集合视图上用animated:YES
标志设置它.预期的行为是单元格不移动.然而,实际行为是单元格滚动到屏幕外,此时甚至不可能将单元格滚动回屏幕上.
查看控制台日志(log)会发现contentOffset莫名其妙地发生了更改(在我的项目中,从(0,0)更改为(0,205)).我发布了solution for the non-animated case(i.e. animated:NO
)的解决方案,但由于我需要动画,我非常想知道是否有人有动画 case 的解决方案或变通方法.
顺便说一句,我测试了自定义布局,并获得了相同的行为.