AutoLayout下CollectionView的自适应大小(二)

    接上一篇文章,继续处理collectionView在使用中出现的问题,若是你没有遇到上面的问题这篇能够跳过了,这里就是处理collectionView中cell的间距不固定的问题。数组

    要让collectionView整齐排布,就要用到flowLayout,这里能够经过继承UICollectionViewFlowLayout来从新对collectionView进行排布,这里能够详细了解下UICollectionViewFlowLayout这个类,它是一个布局类继承自UICollectionViewLayout,下面重点说如下两个ide

- (CGSize)collectionViewContentSize; // Subclasses must override this method and use it to return the width and height of the collection view’s content. These values represent the width and height of all the content, not just the content that is currently visible. The collection view uses this information to configure its own content size to facilitate scrolling.

- (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect; // return an array layout attributes instances for all the views in the given rect

collectionViewContentSize 这个是必须重写的方法,用来返回collectionView的内容的大小,也就是说,并非collectionView自己的大小,eg:collectionView的高度是10,而content的大小是100,那就会有滚动的效果。
布局

layoutAttributesForElementsInRect,这里就是返回全部布局属性的数组,布局属性有什么用,固然就是用来布局的,大小啊,中心点啊,透明度啊。。。具体的能够移步这篇文字去一探究竟this

经过重写这两个方法,就能够从新对content进行布局了,这样每一个cell的排列就能够紧凑起来了
spa

直接上代码
.net

- (CGSize)collectionViewContentSize {
    
    CGSize size = CGSizeZero;
    NSInteger itemCount = 0;
    if ([self.collectionView.dataSource respondsToSelector:@selector(collectionView:numberOfItemsInSection:)]) {
        itemCount = [self.collectionView.dataSource collectionView:self.collectionView numberOfItemsInSection:0];
    }
    if (CGSizeEqualToSize(size, CGSizeZero) && itemCount == 0) {
        return CGSizeZero;
    }

    NSInteger lineWidth = 50;
    NSUInteger rowCount = 1;
    for (int i = 1; i < itemCount; ++i) {
        NSArray* labels = [[MFAppModel sharedObject].chatroomModelEx getFullLabels];
        MFRoomLabel* currentRoomLabel = [labels objectAtIndex:i];
        NSDictionary *attribute = @{NSFontAttributeName: [UIFont systemFontOfSize:15]};
        CGSize currentLabelSize = [currentRoomLabel.name sizeWithAttributes:attribute];
        CGFloat cellWidth = MAX(50, currentLabelSize.width + 16);
        lineWidth = lineWidth + 15 + cellWidth;
        if (lineWidth > (NSInteger)self.collectionView.frame.size.width) {
            rowCount++;
            lineWidth = cellWidth;
        }
    }
    size.width = CGRectGetWidth(self.collectionView.frame);
    size.height = rowCount * self.itemSize.height + (rowCount - 1) * self.minimumLineSpacing  + self.sectionInset.top + self.sectionInset.bottom;
    
    return size;
}
- (NSArray *) layoutAttributesForElementsInRect:(CGRect)rect {
    NSMutableArray* attributes = [[super layoutAttributesForElementsInRect:rect] mutableCopy];

    for(int i = 1; i < [attributes count]; ++i) {
        
        NSArray* labels = [[MFAppModel sharedObject].chatroomModelEx getFullLabels];
        MFRoomLabel* roomLabel = [labels objectAtIndex:i];
        NSDictionary *attribute = @{NSFontAttributeName: [UIFont systemFontOfSize:15]};
        CGSize labelSize = [roomLabel.name sizeWithAttributes:attribute];
        UICollectionViewLayoutAttributes *currentLayoutAttributes = attributes[i];
        UICollectionViewLayoutAttributes *prevLayoutAttributes = attributes[i - 1];
        CGFloat cellWidth = MAX(50, labelSize.width + 16);
        currentLayoutAttributes.size = CGSizeMake(cellWidth, 24);
        NSInteger maximumSpacing = 15;
        NSInteger origin = CGRectGetMaxX(prevLayoutAttributes.frame);
        if (origin + maximumSpacing + currentLayoutAttributes.frame.size.width < self.collectionViewContentSize.width) {
            CGRect frame = currentLayoutAttributes.frame;
            frame.origin.x = origin + maximumSpacing;
            currentLayoutAttributes.frame = frame;
            
        }
    }

    return attributes;
}

这里可能要讲解下layoutAttributesForElementsInRect,这里从第二个开始,每一个cell的位置都是前一个cell的位置+maximumSpacing,若是不超过这一行的最大宽度,就改变当前cell的起始位置和大小(也即frame),若是超过了就不改变,那不改变是什么意思?就是保持原来的位置,这里的原来的位置可能和咱们想象的不太同样,不是一开始定死的位置,而是通过调整后的位置,由于,这里改变前一个cell对后面的cell是好有影响的,好吧,有点深奥,就说这么多吧。code

哦,最后还要在xib或者storyboard中的Identify中修改collectionView的class,这里的MFChatRoomFilterCol就是继承自UICollectionViewFlowLayout的自定义布局,下面是运行的结果。看起来离目标又近了一步。orm

相关文章
相关标签/搜索