具有dynamic高度的UICollectionView不在单元格之间获得相同的空间

我有这样的类似问题

我在运行时产生了高度的视图。这是我的代码

@interface CollectionViewController () { NSMutableArray *arrMain; } @property(nonatomic,strong) NSMutableArray *arrMain; @end @implementation CollectionViewController @synthesize arrMain, - (void)viewDidLoad { [super viewDidLoad]; [cView registerNib:[UINib nibWithNibName:@"CViewCell" bundle:nil] forCellWithReuseIdentifier:kCellID]; CViewFlowLayout *fl = [[CViewFlowLayout alloc] init]; self.cView.collectionViewLayout = fl; NSString *strJson = MY FUNCTION WHICH RETURNS JSON STRING; SBJSON *parser = [[SBJSON alloc] init]; self.arrMain = [[NSMutableArray alloc] init]; self.arrMain = [parser objectWithString:strJson error:nil]; for (int i=0; i<[self.arrMain count]; i++) { NSDictionary *dic = [self.arrMain objectAtIndex:i]; [self setTags:[[UIView alloc] init] selDictionary:dic]; // This function generates height and save it to the dictionary } [cView reloadData]; } - (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section; { return [self.arrMain count]; } - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { NSDictionary *dic = [self.arrMain objectAtIndex:indexPath.row]; return CGSizeMake(236,40+[[dic valueForKey:@"TAGS_HEIGHT"] intValue]); } - (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath; { CViewCell *cell =(CViewCell *) [cv dequeueReusableCellWithReuseIdentifier:kCellID forIndexPath:indexPath]; NSDictionary *dic = [self.arrMain objectAtIndex:indexPath.row]; if ([cell viewWithTag:11]){ [[cell viewWithTag:11] release]; [[cell viewWithTag:11] removeFromSuperview]; } UIView *viewTags = [[UIView alloc] init]; [viewTags setTag:11]; [viewTags setBackgroundColor:[UIColor lightGrayColor]]; [self setTags:viewTags selDictionary:dic]; [viewTags setFrame:CGRectMake(5, 10, CONTENT_WIDTH, [[dic valueForKey:@"TAGS_HEIGHT"] floatValue])]; [cell.contentView addSubview:viewTags]; return cell; } 

我已经尝试了以上链接解决scheme,但它不适合我。 这是我的输出图像。

我需要的间距是相同的。 有没有人有解决这个问题?

这是UICOllectionView的错误吗? 因为我在这篇文章中也发现了这个问题。

我有这种问题的一般解决scheme:

 - (void)viewDidLoad { [super viewDidLoad]; [cView registerNib:[UINib nibWithNibName:@"CViewCell" bundle:nil] forCellWithReuseIdentifier:kCellID]; CViewFlowLayout *fl = [[CViewFlowLayout alloc] init]; fl.minimumInteritemSpacing = 10; fl.scrollDirection = UICollectionViewScrollDirectionVertical; self.cView.collectionViewLayout = fl; NSString *strJson = MY FUNCTION WHICH RETURNS JSON STRING; SBJSON *parser = [[SBJSON alloc] init]; self.arrMain = [[NSMutableArray alloc] init]; self.arrMain = [parser objectWithString:strJson error:nil]; for (int i=0; i<[self.arrMain count]; i++) { NSDictionary *dic = [self.arrMain objectAtIndex:i]; [self setTags:[[UIView alloc] init] selDictionary:dic]; // This function generates height and save it to the dictionary } [cView reloadData]; 

}

然后,更新CViewFlowLayout.m中的代码,该代码是UICollectionViewFlowLayout的子类。

这里是代码:

 #define numColumns 3 @implementation CViewFlowLayout @synthesize numOfColumnsToDisplay; - (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; } - (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; } 

这个解决scheme只适用于垂直滚动。 如果要显示更多或更less的列,只需更改numColumns

尝试这个:

 - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { return CGSizeMake(250, 150); } 

在Storybord或xib设置值中看到这个! 在这里输入图像说明

您从UICollectionViewFlowLayoutinheritance的类必须包含方法:

 - (CGSize)collectionViewContentSize { return CGSizeMake(200, 200) // as per your cell size } - (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; } - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath { UICollectionViewLayoutAttributes* currentItemAttributes = [super layoutAttributesForItemAtIndexPath:indexPath]; if (!currentItemAttributes) { currentItemAttributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; } return currentItemAttributes; } 

并在你的CollectionViewController中添加

 #pragma mark - Collection View Datasource - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { // Adjust cell size for orientation if (UIDeviceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) { return CGSizeMake(150, 230); } return CGSizeMake(150, 230); } 

您可以设置一个属性的大小:

 flowLayout.headerReferenceSize = CGSizeMake(0, 100);//constant height for all the items header 

如果dynamic:

 - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section { if (section == albumSection) { return CGSizeMake(0, 100); } return CGSizeZero; } 

使用以下方法

//迅速

 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize{ return CGSizeMake(250, 150); } 

// Objective C

 -(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { return CGSizeMake(250, 150); }