最近在开发软件的时候被要求,要让UICollectionView上面的cell之间的距离固定,但是cell的宽度不一定,所以一行有几个cell其实不固定,跟cell中的label的text有关,剩下的空白格平均分配的. 效果如下:
首先控制cell间的间距固定,左边对齐(这部分,我主要参照文章UICollectionView中Cell左对齐 居中 右对齐 等间距)
EqualSpaceFlowLayoutEvolve继承UICollectionViewFlowLayout。 .m文件的代码如下:
-(instancetype)init{
if(self = [super init]){
self.scrollDirection = UICollectionViewScrollDirectionVertical;
self.minimumLineSpacing =5;
self.minimumInteritemSpacing =5;
self.sectionInset = UIEdgeInsetsMake(0,0,0,0);
_betweenOfCell = 5.0;
_cellType = AlignWithLeft;
}
return self;
}
-(void)setBetweenOfCell:(CGFloat)betweenOfCell{
_betweenOfCell = betweenOfCell;
self.minimumInteritemSpacing = betweenOfCell;
}
-(instancetype)initWthType:(AlignType)cellType{
if(self = [super init]){
self.scrollDirection = UICollectionViewScrollDirectionVertical;
self.minimumLineSpacing =5;
self.minimumInteritemSpacing =5;
self.sectionInset = UIEdgeInsetsMake(0,0,0,0);
_betweenOfCell =5.0;
_cellType = cellType;
}
return self;
}
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
NSArray *layoutAttributes_t = [super layoutAttributesForElementsInRect:rect];
NSArray *layoutAttributes = [[NSArray alloc] initWithArray:layoutAttributes_t copyItems:YES];
//用来临时存放一行的Cell数组
NSMutableArray *layoutAttributesTemp = [[NSMutableArray alloc] init];
for(NSUInteger index =0; index < layoutAttributes.count ; index++) {
UICollectionViewLayoutAttributes *currentAttr = layoutAttributes[index];// 当前cell的位置信息
UICollectionViewLayoutAttributes *previousAttr = index ==0? nil : layoutAttributes[index-1];// 上一个cell 的位置信
UICollectionViewLayoutAttributes *nextAttr = index +1== layoutAttributes.count ? nil : layoutAttributes[index+1];//下一个cell 位置信息
//加入临时数组
[layoutAttributesTemp addObject:currentAttr];
_sumWidth += currentAttr.frame.size.width;
CGFloat previousY = previousAttr == nil ? 0: CGRectGetMaxY(previousAttr.frame);
CGFloat currentY = CGRectGetMaxY(currentAttr.frame);
CGFloat nextY = nextAttr == nil ?0: CGRectGetMaxY(nextAttr.frame);
//如果当前cell是单独一行
if(currentY != previousY && currentY != nextY){
if([currentAttr.representedElementKind isEqualToString:UICollectionElementKindSectionHeader]) {
[layoutAttributesTemp removeAllObjects];
_sumWidth =0.0;
}else if([currentAttr.representedElementKind isEqualToString:UICollectionElementKindSectionFooter]){
[layoutAttributesTemp removeAllObjects];
_sumWidth =0.0;
}else{
[self setCellFrameWith:layoutAttributesTemp];
}
}
//如果下一个cell在本行,这开始调整Frame位置
else if( currentY != nextY) {
[self setCellFrameWith:layoutAttributesTemp];
}
}
return layoutAttributes;
}
-(void)setCellFrameWith:(NSMutableArray*)layoutAttributes{
CGFloat nowWidth =0.0;
switch(_cellType) {
case AlignWithLeft: {
nowWidth = self.sectionInset.left;
for(UICollectionViewLayoutAttributes * attributesinlayoutAttributes) {
CGRect nowFrame = attributes.frame;
nowFrame.origin.x = nowWidth;
attributes.frame = nowFrame;
nowWidth += nowFrame.size.width + self.betweenOfCell;
}
_sumWidth =0.0;
[layoutAttributes removeAllObjects];
}
break;
case AlignWithCenter: {
nowWidth = (self.collectionView.frame.size.width - _sumWidth - ((layoutAttributes.count -1) * _betweenOfCell)) /2;
for(UICollectionViewLayoutAttributes * attributesinlayoutAttributes) {
CGRect nowFrame = attributes.frame;
nowFrame.origin.x = nowWidth;
attributes.frame = nowFrame;
nowWidth += nowFrame.size.width + self.betweenOfCell;
}
_sumWidth =0.0;
[layoutAttributes removeAllObjects];
}
break;
case AlignWithRight: {
nowWidth = self.collectionView.frame.size.width - self.sectionInset.right;
for(NSInteger index = layoutAttributes.count -1; index >=0; index-- ) {
UICollectionViewLayoutAttributes * attributes = layoutAttributes[index];
CGRect nowFrame = attributes.frame;
nowFrame.origin.x = nowWidth - nowFrame.size.width;
attributes.frame = nowFrame;
nowWidth = nowWidth - nowFrame.size.width - _betweenOfCell;
if(index ==0) {
CGRect nowFrame = attributes.frame;
nowFrame.origin.x = nowWidth;
attributes.frame = nowFrame;
}
}
_sumWidth =0.0;
[layoutAttributes removeAllObjects];
}
break;
}
}
然后在创建collectionView的地方写下如下代码:
EqualSpaceFlowLayoutEvolve *flowLayout = [[EqualSpaceFlowLayoutEvolve alloc] initWthType:AlignWithLeft];
flowLayout.betweenOfCell =15;
flowLayout.scrollDirection = UICollectionViewScrollDirectionVertical;
flowLayout.sectionInset = UIEdgeInsetsMake(0,0,0,0);
_collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0,0,100,100) collectionViewLayout:flowLayout];
就这样就可以控制cell的间距固定,左边对齐了
cell右边对齐
首先一个数组存cell上label的text,然后调用一下方法:
- (void)calculateItemWidthsWith:(NSArray *)array{
_itemWidths = [NSMutableArray array];
CGFloat maxWidth = self.view.frame.size.width -40;
CGFloat sumWidth =0;
int count =0;
for(inti =0; i < array.count; i++) {
CGFloat itemWidth = [array[i] boundingRectWithSize:CGSizeMake(maxWidth,33) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading | NSStringDrawingTruncatesLastVisibleLine attributes:@{NSFontAttributeName: [UIFont systemFontOfSize:15]} context:nil].size.width +45;
itemWidth = itemWidth > maxWidth ? maxWidth : itemWidth;
sumWidth += itemWidth;
count +=1;
if(sumWidth > maxWidth && i !=0) {
// XXX: 在iPhone5下,得减去一点点数值(0.00001),cell排序才不会乱
CGFloat subWidth = maxWidth - (sumWidth - itemWidth) -0.00001;
CGFloat space = subWidth/(count -1);
for(inth =1; h < count; h++) {
self.itemWidths[i-h] = [NSString stringWithFormat:@"%f", [_itemWidths[i-h] floatValue] + space];
}
sumWidth = itemWidth;
count =1;
}
[_itemWidths addObject:[NSString stringWithFormat:@"%f", itemWidth]];
}
}
最后调用一下方法即可
#pragma mark -
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
return CGSizeMake([self.itemWidths[indexPath.row] floatValue] -15,33);
}