上次介绍了分组自定义流布局方法一,这次介绍方法二,这次的主要思路是在layout里直接解决。好了废话不多说,直接上代码。
.h文件中:
#import <UIKit/UIKit.h>
@protocol JYCollectionViewFlowLayoutDelegate <UICollectionViewDelegateFlowLayout>
@optional
-(UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section;
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout heightForHeaderInSection:(NSInteger)section;
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout heightForFooterInSection:(NSInteger)section;
@end
@interface JYCollectionViewFlowLayout :UICollectionViewFlowLayout
@property (nonatomic,weak) id<JYCollectionViewFlowLayoutDelegate> delegate;
@property (nonatomic,assign) CGFloat headerHeight;// default 0
@property (nonatomic,assign) CGFloat footerHeight;// default 0
@end
.m文件中:#import "JYCollectionViewFlowLayout.h"
#define WIDTH self.collectionView.frame.size.width
@interface JYCollectionViewFlowLayout ()
@property(nonatomic,strong)NSArray <UICollectionViewLayoutAttributes *> *itemsAttributes;
@property (nonatomic,assign) CGFloat contentHeight;
@property (nonatomic,strong) NSMutableArray *supplementaryAttributes;
@end
@implementation JYCollectionViewFlowLayout
-(instancetype)init{
if (self = [superinit]) {
self.minimumLineSpacing =0;
self.minimumInteritemSpacing =0;
_supplementaryAttributes = [[NSMutableArrayalloc]init];
}
returnself;
}
-(void)prepareLayout{
NSInteger countSection = [self.collectionViewnumberOfSections];
//创建一个临时可变数组暂时盛放布局
NSMutableArray *arr=[[NSMutableArrayalloc]init];
for (NSInteger section =0; section < countSection; section++) {//
NSInteger count = [self.collectionViewnumberOfItemsInSection:section];
//这个属性,这里暂时用不到
// CGFloat minimumInteritemSpacing = [self minimumInteritemSpacingForSection:section];
// CGFloat minimumLineSpacing = [self minimumLineSpacingForSection:section];
UIEdgeInsets sectionInset = [selfsectionInsetForSection:section];
CGFloat headerHeight = [selfheaderHeightForSection:section];
CGFloat footerHeight = [selffooterHeightForSection:section];
self.contentHeight += sectionInset.top;
NSMutableDictionary *supplementary = [[NSMutableDictionaryalloc] initWithCapacity:2];
UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributeslayoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeaderwithIndexPath:[NSIndexPathindexPathForItem:0inSection:section]];
attributes.frame =CGRectMake(0,self.contentHeight,self.collectionView.frame.size.width, headerHeight);
self.contentHeight += headerHeight;
[arr addObject:attributes];
[supplementary setObject:attributesforKey:UICollectionElementKindSectionHeader];
for (NSInteger row =0; row<count; row++) {
//创建布局属性
UICollectionViewLayoutAttributes *att = [UICollectionViewLayoutAttributeslayoutAttributesForCellWithIndexPath:[NSIndexPathindexPathForItem:rowinSection:section]];
CGRect itemFrame;
switch (count) {
case1:
itemFrame = [selfimagesOfOneWith:row];
break;
case2:
itemFrame = [selfimagesOfTwoWith:row];
break;
case3:
itemFrame = [selfimagesOfThreeWith:row];
break;
case4:
itemFrame = [selfimagesOfFourWith:row];
break;
case5:
itemFrame = [selfimagesOfFiveWith:row];
break;
case6:
itemFrame = [selfimagesOfSixWith:row];
break;
case7:
itemFrame = [selfimagesOfSevenWith:row];
break;
case8:
itemFrame = [selfimagesOfEightWith:row];
break;
case9:
itemFrame = [selfimagesOfNineWith:row];
break;
case10:
itemFrame = [selfimagesOfTenWith:row];
break;
default:
break;
}
CGRect rect = itemFrame;
att.frame =CGRectMake(rect.origin.x, rect.origin.y+self.contentHeight, rect.size.width, rect.size.height);
[arr addObject:att];
}
switch (count) {
case1:
self.contentHeight+=WIDTH/2;
break;
case2:
self.contentHeight+=WIDTH/2;
break;
case3:
self.contentHeight+=WIDTH;
break;
case4:
self.contentHeight+=WIDTH*5/6;
break;
case5:
self.contentHeight+=WIDTH*7/6;
break;
case6:
self.contentHeight+=WIDTH;
break;
case7:
self.contentHeight+=WIDTH*7/6;
break;
case8:
self.contentHeight+=WIDTH*7/6;
break;
case9:
self.contentHeight+=WIDTH;
break;
case10:
self.contentHeight+=WIDTH;
break;
default:
break;
}
UICollectionViewLayoutAttributes *attributes1 = [UICollectionViewLayoutAttributeslayoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionFooterwithIndexPath:[NSIndexPathindexPathForItem:0inSection:section]];
attributes1.frame =CGRectMake(0,self.contentHeight,self.collectionView.frame.size.width, footerHeight);
self.contentHeight +=footerHeight;
[arr addObject:attributes1];
[supplementary setObject:attributes1forKey:UICollectionElementKindSectionFooter];
[self.supplementaryAttributesaddObject:supplementary];
self.contentHeight += sectionInset.bottom;
// self.contentHeight += minimumLineSpacing;
}
self.itemsAttributes = [arrcopy];
}
- (CGSize)collectionViewContentSize
{
returnCGSizeMake(self.collectionView.frame.size.width,self.contentHeight);
}
- (nullableNSArray<__kindofUICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
{
NSPredicate *pred = [NSPredicatepredicateWithBlock:^BOOL(UICollectionViewLayoutAttributes *evaluatedObject,NSDictionary<NSString *,id> *_Nullable bindings) {
returnCGRectIntersectsRect(rect, evaluatedObject.frame);
}];
NSArray *arr = [self.itemsAttributesfilteredArrayUsingPredicate:pred];
return arr;
returnself.itemsAttributes;
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
returnself.supplementaryAttributes[indexPath.section][kind];
}
#pragma mark-不同数量的布局
-(CGRect)imagesOfOneWith:(NSInteger)row{
returnCGRectMake(0,0, WIDTH,WIDTH/2);
}
-(CGRect)imagesOfTwoWith:(NSInteger)row{
CGFloat _w =WIDTH/2;
CGRect itemFrame;
switch (row) {
case0:
itemFrame = CGRectMake(0,0, _w, WIDTH/2);
break;
case1:
itemFrame = CGRectMake(_w,0, _w, WIDTH/2);
break;
default:
break;
}
return itemFrame;
}
-(CGRect)imagesOfThreeWith:(NSInteger)row{
CGFloat bigH =WIDTH/2;
CGFloat smallH = bigH;
CGFloat smallW =WIDTH/2;
CGRect itemFrame;
switch (row) {
case0:
itemFrame = CGRectMake(0,0, WIDTH, bigH);
break;
case1:
itemFrame = CGRectMake(0, bigH, smallW, smallH);
break;
case2:
itemFrame = CGRectMake(smallW, bigH, smallW, smallH);
break;
default:
break;
}
return itemFrame;
}
-(CGRect)imagesOfFourWith:(NSInteger)row{
CGFloat bigH =WIDTH/2;
CGFloat smallW =WIDTH/3;
CGRect itemFrame;
switch (row) {
case0:
itemFrame = CGRectMake(0,0, WIDTH, bigH);
break;
case1:
itemFrame = CGRectMake(0, bigH, smallW, smallW);
break;
case2:
itemFrame = CGRectMake(smallW, bigH, smallW, smallW);
break;
case3:
itemFrame = CGRectMake(smallW*2, bigH, smallW, smallW);
break;
default:
break;
}
return itemFrame;
}
-(CGRect)imagesOfFiveWith:(NSInteger)row{
CGFloat rightW =WIDTH/3;
CGFloat bigH = rightW *2;
CGFloat downW =WIDTH/2;
CGRect itemFrame;
switch (row) {
case0:
itemFrame = CGRectMake(0,0, bigH, bigH);
break;
case1:
itemFrame = CGRectMake(bigH,0, rightW, rightW);
break;
case2:
itemFrame = CGRectMake(bigH, rightW, rightW, rightW);
break;
case3:
itemFrame = CGRectMake(0, bigH, downW, downW);
break;
case4:
itemFrame = CGRectMake(downW, bigH, downW, downW);
break;
default:
break;
}
return itemFrame;
}
-(CGRect)imagesOfSixWith:(NSInteger)row{
CGFloat small =WIDTH/3;
CGFloat bigH = small *2;
CGRect itemFrame;
switch (row) {
case0:
itemFrame = CGRectMake(0,0, bigH, bigH);
break;
case1:
itemFrame = CGRectMake(bigH,0, small, small);
break;
case2:
itemFrame = CGRectMake(bigH, small, small, small);
break;
case3:
itemFrame = CGRectMake(0, bigH, small, small);
break;
case4:
itemFrame = CGRectMake(small, bigH, small, small);
break;
case5:
itemFrame = CGRectMake(small*2, bigH, small, small);
break;
default:
break;
}
return itemFrame;
}
-(CGRect)imagesOfSevenWith:(NSInteger)row{
CGFloat bigH =WIDTH/2;
CGFloat small =WIDTH/3;
CGRect itemFrame;
switch (row) {
case0:
itemFrame = CGRectMake(0,0, WIDTH, bigH);
break;
case1:
itemFrame = CGRectMake(0, bigH, small, small);
break;
case2:
itemFrame = CGRectMake(small, bigH, small, small);
break;
case3:
itemFrame = CGRectMake(small*2, bigH, small, small);
break;
case4:
itemFrame = CGRectMake(0, bigH+small, small, small);
break;
case5:
itemFrame = CGRectMake(small, bigH+small, small, small);
break;
case6:
itemFrame = CGRectMake(small*2, bigH+small, small, small);
break;
default:
break;
}
return itemFrame;
}
-(CGRect)imagesOfEightWith:(NSInteger)row{
CGFloat bigH =WIDTH/2;
CGFloat small =WIDTH/3;
CGRect itemFrame;
switch (row) {
case0:
itemFrame = CGRectMake(0,0, bigH, bigH);
break;
case1:
itemFrame = CGRectMake(bigH,0, bigH, bigH);
break;
case2:
itemFrame = CGRectMake(0, bigH, small, small);
break;
case3:
itemFrame = CGRectMake(small, bigH, small, small);
break;
case4:
itemFrame = CGRectMake(small*2, bigH, small, small);
break;
case5:
itemFrame = CGRectMake(0, bigH+small, small, small);
break;
case6:
itemFrame = CGRectMake(small, bigH+small, small, small);
break;
case7:
itemFrame = CGRectMake(small*2, bigH+small, small, small);
break;
default:
break;
}
return itemFrame;
}
-(CGRect)imagesOfNineWith:(NSInteger)row{
CGFloat bigH =WIDTH/2;
CGFloat small =WIDTH/4;
CGRect itemFrame;
switch (row) {
case0:
itemFrame = CGRectMake(0,0, WIDTH, bigH);
break;
case1:
itemFrame = CGRectMake(0, bigH, small, small);
break;
case2:
itemFrame = CGRectMake(small, bigH, small, small);
break;
case3:
itemFrame = CGRectMake(small*2, bigH, small, small);
break;
case4:
itemFrame = CGRectMake(small*3, bigH, small, small);
break;
case5:
itemFrame = CGRectMake(0, bigH+small, small, small);
break;
case6:
itemFrame = CGRectMake(small, bigH+small, small, small);
break;
case7:
itemFrame = CGRectMake(small*2, bigH+small, small, small);
break;
case8:
itemFrame = CGRectMake(small*3, bigH+small, small, small);
break;
default:
break;
}
return itemFrame;
}
-(CGRect)imagesOfTenWith:(NSInteger)row{
CGFloat bigH =WIDTH/2;
CGFloat small =WIDTH/4;
CGRect itemFrame;
switch (row) {
case0:
itemFrame = CGRectMake(0,0, bigH, bigH);
break;
case1:
itemFrame = CGRectMake(bigH,0, bigH, bigH);
break;
case2:
itemFrame = CGRectMake(0, bigH, small, small);
break;
case3:
itemFrame = CGRectMake(small, bigH, small, small);
break;
case4:
itemFrame = CGRectMake(small*2, bigH, small, small);
break;
case5:
itemFrame = CGRectMake(small*3, bigH, small, small);
break;
case6:
itemFrame = CGRectMake(0, bigH+small, small, small);
break;
case7:
itemFrame = CGRectMake(small, bigH+small, small, small);
break;
case8:
itemFrame = CGRectMake(small*2, bigH+small, small, small);
break;
case9:
itemFrame = CGRectMake(small*3, bigH+small, small, small);
break;
default:
break;
}
return itemFrame;
}
#pragma mark -
- (CGFloat)headerHeightForSection:(NSInteger)section
{
if ([self.delegaterespondsToSelector:@selector(collectionView:layout:heightForHeaderInSection:)]) {
self.headerHeight = [self.delegatecollectionView:self.collectionViewlayout:selfheightForHeaderInSection:section];
}
returnself.headerHeight;
}
- (CGFloat)footerHeightForSection:(NSInteger)section
{
if ([self.delegaterespondsToSelector:@selector(collectionView:layout:heightForFooterInSection:)]) {
self.footerHeight = [self.delegatecollectionView:self.collectionViewlayout:selfheightForFooterInSection:section];
}
returnself.footerHeight;
}
- (UIEdgeInsets)sectionInsetForSection:(NSInteger)section
{
if ([self.delegaterespondsToSelector:@selector(collectionView:layout:insetForSectionAtIndex:)]) {
self.sectionInset = [self.delegatecollectionView:self.collectionViewlayout:selfinsetForSectionAtIndex:section];
}
returnself.sectionInset;
}
#pragma mark -这个demo里面用不到,这里先先写上
- (CGFloat)minimumLineSpacingForSection:(NSInteger)section
{
if ([self.delegaterespondsToSelector:@selector(collectionView:layout:minimumLineSpacingForSectionAtIndex:)]) {
self.minimumLineSpacing = [self.delegatecollectionView:self.collectionViewlayout:selfminimumLineSpacingForSectionAtIndex:section];
}
returnself.minimumLineSpacing;
}
- (CGFloat)minimumInteritemSpacingForSection:(NSInteger)section
{
if ([self.delegaterespondsToSelector:@selector(collectionView:layout:minimumInteritemSpacingForSectionAtIndex:)]) {
self.minimumInteritemSpacing = [self.delegatecollectionView:self.collectionViewlayout:selfminimumInteritemSpacingForSectionAtIndex:section];
}
returnself.minimumInteritemSpacing;
}
@end
下面是效果图:
下面是下载地址:https://github.com/markwangjy/SectionCollectionView_two.git
谢谢大家阅读,我是ios_mark qq:1124728522 欢迎大家多多批评指正。