具有dynamic高度的UICollectionView错误

由于我一直在这个问题上挣扎了3天,并且已经问了两次,但是可能还不清楚,所以我决定调查这个问题,并且发现了这个问题。

我会显示整个简单的代码,所以任何人都可以重现的错误(iPad空气)。

我正在设置一个collectionViewstream布局,使布局子类化以获得单元格之间的恒定间距,这里是开始:

  TopAlignedCollectionViewFlowLayout *layout = [[TopAlignedCollectionViewFlowLayout alloc] init]; CGRect size = CGRectMake(0, 0, 900, 1200); self.GridView = [[UICollectionView alloc] initWithFrame:size collectionViewLayout:layout]; [self.GridView registerClass:[GridCell class] forCellWithReuseIdentifier:@"Cell"]; [self.GridView setDelegate:self]; [self.GridView setDataSource:self]; [self.view addSubview:self.GridView]; 

然后设置我的委托是这样简单:( 高度是dynamic的

 #pragma grid- main functions -(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { return 1; } -(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return 80; } //cell size - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath; { //a random dynamic height of a cell int a = arc4random()%300; CGSize size = CGSizeMake( 340, 240+a ); return size; } -(UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellIdentifier=@"Cell"; GridCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath]; cell.textL.text=[NSString stringWithFormat:@"%d",indexPath.row]; NSLog(@"%d",indexPath.row); return cell; } 

现在的子类,得到一个不变的间距:( TopAlignedCollectionViewFlowLayout

 - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { NSArray* attributesToReturn = [super layoutAttributesForElementsInRect:rect]; for (UICollectionViewLayoutAttributes* attributes in attributesToReturn) { if (nil == attributes.representedElementKind) { NSIndexPath* indexPath = attributes.indexPath; attributes.frame = [self layoutAttributesForItemAtIndexPath:indexPath].frame; } } return attributesToReturn; } #define numColumns 2 - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath { UICollectionViewLayoutAttributes* currentItemAttributes = [super layoutAttributesForItemAtIndexPath:indexPath]; if (indexPath.item < numColumns) { CGRect f = currentItemAttributes.frame; f.origin.y = 0; currentItemAttributes.frame = f; return currentItemAttributes; } NSIndexPath* ipPrev = [NSIndexPath indexPathForItem:indexPath.item-numColumns inSection:indexPath.section]; CGRect fPrev = [self layoutAttributesForItemAtIndexPath:ipPrev].frame; CGFloat YPointNew = fPrev.origin.y + fPrev.size.height + 10; CGRect f = currentItemAttributes.frame; f.origin.y = YPointNew; currentItemAttributes.frame = f; return currentItemAttributes; } 

任何人都可以检查并看到,在您滚动一段时间之后,您会看到一个奇怪的效果:最近由它们的单元格填充的空格,如下所示:

  1 2 3 4 6 8 

注:5-7稍后加载。


EDIT1:

从单元格大小的委托方法中删除随机高度,将其设置为不变的高度,解决了这个问题。
问题是:单元格的高度必须是dynamic的。

EDIT2:设置随机高度(int a)变小,也使问题消失,(<100)意味着单元之间的距离高度越小,出现问题的可能性越大。

编辑3!

我已经设置了单元格之间的恒定距离,而不是布局的子类,但是通过保存以前的单元格的原点和高度来保存我自己的内存, 所以我得到了恒定的间距,但问题又回来了 ! 似乎如果单元格在一定的结构中,它使得callback方法创build单元格,不被及时调用! 哇,我真的想知道如何没有人见过这之前..这是我的实现创build没有子类的间距,这也导致了问题:

 -(UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellIdentifier=@"Cell"; GridCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath]; cell.textL.text=[NSString stringWithFormat:@"%ld",(long)indexPath.row]; NSLog(@"%d",indexPath.row); if(indexPath.row>1) { NSIndexPath* ipPrev = [NSIndexPath indexPathForItem:indexPath.item-2 inSection:indexPath.section]; float prey=[[[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:@"y:%ld",(long)ipPrev.row]] floatValue]; float preh=[[[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:@"h:%ld",(long)ipPrev.row]] floatValue]; cell.frame=CGRectMake(cell.frame.origin.x, preh+prey+10, cell.frame.size.width, cell.frame.size.height); [[NSUserDefaults standardUserDefaults] setFloat:cell.frame.origin.y forKey:[NSString stringWithFormat:@"y:%ld",(long)indexPath.row]]; [[NSUserDefaults standardUserDefaults] setFloat:cell.frame.size.height forKey:[NSString stringWithFormat:@"h:%ld",(long)indexPath.row]]; [[NSUserDefaults standardUserDefaults] synchronize]; NSLog(@"this index:%d",indexPath.row); NSLog(@"this cell y:%f",cell.frame.origin.y); NSLog(@"this cell height:%f",cell.frame.size.height); NSLog(@"previous index:%ld",(long)ipPrev.row); NSLog(@"previous cell y: %@",[[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:@"y:%ld",(long)ipPrev.row]]); NSLog(@"previous cell height: %@",[[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:@"h:%ld",(long)ipPrev.row]]); NSLog(@"------------------------"); } return cell; } 

在UICollectionView中,当图像大于屏幕尺寸时,看起来是一个严重的错误。

1。 UICollectionView回退到UIScrollView

2. 大的UICollectionViewCell随着自定义布局而消失

3. http://stripysock.com.au/blog/2013/3/14/working-around-a-bug-in-uicollectionview

这么多的工作和时间,对于这个可重复使用的细胞的苹果这个愚蠢的错误,除了头痛之外,还有许多奇怪的行为。

对于那些没有这个问题的开发者,我可以说 – 只是设置dynamic高度图像和iPad模拟器,你会看到一些令人难以置信的错误。

所以没有答案,我将不得不通过我的自我实现整个事情与scrollview,因为我不想再被依赖的东西,如PSTCollectionView