FMLayoutKit
簡(jiǎn)介
一個(gè)可以讓你更快的搞定復(fù)雜頁面(電商首頁响谓,方格+列表多樣式布局)的CollectionView自定義布局窄锅,目前僅支持縱向布局簸淀,可以穿插橫向布局,動(dòng)態(tài)cell高度做一些適配可以做到自動(dòng)計(jì)算高度角塑,也可以手動(dòng)計(jì)算通過block返回,代碼可以高度集中在一塊慨代,效果下面有演示息罗,有什么問題隨時(shí)issue我疚鲤,感謝Star
安裝方式
已發(fā)布到CocoaPods. podfile中添加以下代碼:
pod 'FMLayoutKit'
Spec的官方源實(shí)在拉取不下來的話锥累,可以用我自己的一個(gè)Spec倉(cāng):
https://gitee.com/Coder_FM/FMPodSpec.git
提示
使用動(dòng)態(tài)自動(dòng)計(jì)算高度的時(shí)候 label的preferredMaxLayoutWidth屬性請(qǐng)給一個(gè)準(zhǔn)確的值 否則計(jì)算label布局的高度不準(zhǔn)確
支持的Cell布局樣式以及頭部懸停效果
分組Cell樣式1
單一Cell,固定大小集歇,支持多列揩悄,從左往右,從上往下布局
分組Cell樣式2
單一Cell鬼悠,固定大小,支持最大行數(shù)亏娜,從左往右焕窝,如果當(dāng)前屏幕夠放,不會(huì)滾動(dòng)维贺,多的才會(huì)滾動(dòng)
分組Cell樣式3
可以多種Cell它掂,block返回每一個(gè)item的大小,從左往右溯泣,從上往下虐秋,尋找最合適的位置放
分組Cell樣式4
瀑布流樣式,支持多種cell樣式垃沦,單列就是列表樣式客给,列表可變,高度可以通過手動(dòng)計(jì)算肢簿,也可以通過autolayout布局自動(dòng)計(jì)算(續(xù)配置數(shù)據(jù))
分組Cell樣式5
標(biāo)簽式布局靶剑,支持單種cell,可以單行滾動(dòng)池充,也可以縱向布局桩引,可限制最大行數(shù)(歷史搜索記錄那種樣式)
分組頭部支持的樣式有4種
- 一般樣式跟著滾動(dòng)
- 懸浮跟著分組滾動(dòng)
- 一直懸浮,滾動(dòng)置頂樣式
- 第一個(gè)分組下拉放大效果(效果無法截圖)
多屏滑動(dòng)效果
每一個(gè)分組都可以設(shè)置頭部收夸,底部坑匠,背景,這三個(gè)都有inset可以設(shè)置內(nèi)邊距卧惜,靈活多變
特斯拉滾動(dòng)視圖是基于FMLayoutView的厘灼,共享的頭部是一個(gè)FMLayoutView,橫向每一屏都是FMLayoutView序苏,最底部可以橫向滾動(dòng)是一個(gè)ScrollView手幢,當(dāng)觸摸到頭部的時(shí)候,ScrollView的pan手勢(shì)會(huì)失效忱详,橫向滾動(dòng)時(shí)围来,會(huì)將共享的頭部移到最頂部視圖上,滾動(dòng)結(jié)束靜止下來的時(shí)候,會(huì)將共享頭部加到當(dāng)前上下滾動(dòng)的FMLayoutView监透,以達(dá)到效果
使用示例
/// 創(chuàng)建CollectionView delegate以及dataSource默認(rèn)自己已遵守實(shí)現(xiàn)了一些方法
FMLayoutView *view = [[FMLayoutView alloc] init];
/// 需要布局的分組
[view.layout setSections:self.shareSections];
view.backgroundColor = [UIColor whiteColor];
[self.view addSubview:view];
[view mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.bottom.mas_equalTo(0);
make.top.mas_equalTo(100);
}];
self.collectionView = view;
/// 固定大小 單一cell樣式的分組
FMLayoutFixedSection *section = [FMLayoutFixedSection sectionWithSectionInset:UIEdgeInsetsMake(0, 15, 15, 15) itemSpace:10 lineSpace:10 column:2];
/// 配置分組頭部 高度以及view類
section.header = [FMSupplementaryHeader supplementaryHeight:100 viewClass:[FMCollectionCustomDecoration class]];
/// 頭部最底距離item的間距
section.header.bottomMargin = 10;
/// 頭部樣式是否懸停
section.header.type = FMSupplementaryTypeSuspensionBigger;
/// 頭部?jī)?nèi)邊距
section.header.inset = UIEdgeInsetsMake(0, -15, 0, -15);
///
[section setConfigureHeaderData:^(FMLayoutBaseSection * _Nonnull section, UICollectionReusableView * _Nonnull header) {
FMCollectionCustomDecoration *customHeader = (FMCollectionCustomDecoration *)header;
customHeader.textLabel.text = @"固定大小, 從左往右從上往下排的分組, 頭部放大縮放效果";
}];
/// 配置分組底部
section.footer = [FMSupplementaryFooter supplementaryHeight:50 viewClass:[FMCollectionCustomDecoration class]];
section.footer.topMargin = 10;
/// 配置Item樣式
/// 是否可以橫向滾動(dòng)
section.isHorizontalCanScroll = YES;
section.itemSize = CGSizeMake(100, 100);
section.itemDatas = [@[@"1", @"2", @"3"] mutableCopy];
/// cell的類 可以純代碼也可以Xib
section.cellElement = [FMCollectionViewElement elementWithViewClass:[FMCollectionCustomCell class]];
/// cell賦值數(shù)據(jù)
[section setConfigureCellData:^(FMLayoutBaseSection * _Nonnull section, UICollectionViewCell * _Nonnull cell, NSInteger item) {
}];
/// cell點(diǎn)擊事件
[section setClickCellBlock:^(FMLayoutBaseSection * _Nonnull section, NSInteger item) {
FMAddViewController *add = [[FMAddViewController alloc] init];
[self.navigationController pushViewController:add animated:YES];
}];
#pragma mark --- 動(dòng)態(tài)分組
/// cell類的數(shù)組
section.cellElements = @[[FMLayoutElement elementWithViewClass:[FMCollectionCustomCell class]]];
/// 需固定寬度
section.cellFixedWidth = [UIScreen mainScreen].bounds.size.width;
/// 手動(dòng)計(jì)算高度
[section setHeightBlock:^CGFloat(id _Nonnull section, NSInteger item) {
return 100 + item * 100;
}];
/// 或者可以自動(dòng)計(jì)算高度 布局約束好 數(shù)據(jù)填充完
section.autoHeightFixedWidth = YES;
/// 對(duì)應(yīng)index需要返回的reusedId來取對(duì)應(yīng)的cell
[section setDeqCellReturnReuseId:^NSString * _Nonnull(FMLayoutDynamicSection * _Nonnull section, NSInteger index) {
return [section.cellElements firstObject].reuseIdentifier;
}];
#pragma mark --- 標(biāo)簽分組
/// 是否是單行滾動(dòng)
section.isSingleLineCanScroll = YES;
/// 不是單行的話 可以限制最大行數(shù)
section.maxLine = 6;
/// 固定每一個(gè)高度
section.cellFixedHeight = 40;
/// 返回對(duì)應(yīng)的寬度
[section setWidthBlock:^CGFloat(id _Nonnull section, NSInteger item) {
return item * 20 + 100;
}];
#pragma mark --- 填充布局分組
/// 需返回大小 插入到合適的位置
[section setSizeBlock:^CGSize(id _Nonnull section, NSInteger item) {
switch (item) {
case 2:
return CGSizeMake(150, 140.32);
case 5:
return CGSizeMake((self.view.frame.size.width-20-150)/2, 70.19);
case 8:
case 11:
return CGSizeMake(100, 240);
case 10:
return CGSizeMake(self.view.frame.size.width-20-200, 140);
case 9:
case 12:
return CGSizeMake(self.view.frame.size.width-20-100, 100);
case 0:
case 1:
case 3:
case 4:
return CGSizeMake((self.view.frame.size.width-20-150)/4, 70.13);
default:
return CGSizeMake((self.view.frame.size.width-20-150)/4, 70.19);
}
}];
#pragma mark --- 特斯拉組件的使用說明 內(nèi)部都是FMLayoutView的組合
/// 創(chuàng)建組件 遵守代理并實(shí)現(xiàn)必須的方法
FMTeslaLayoutView *multi = [[FMTeslaLayoutView alloc] init];
multi.delegate = self;
multi.dataSource = self;
[self.view addSubview:multi];
/// 懸停頭部的最小高度 伸縮動(dòng)畫用
- (CGFloat)shareSuspensionMinHeightWithTesla:(FMTeslaLayoutView *)tesla{
return 70;
}
/// 即將創(chuàng)建FMLayoutView 每一個(gè)分頁只創(chuàng)建一個(gè) 懶加載
- (void)tesla:(FMTeslaLayoutView *)tesla willCreateLayoutViewWithIndex:(NSInteger)index{
NSLog(@"willCreateLayoutViewWithIndex %ld", (long)index);
}
// 已創(chuàng)建FMLayoutView
- (void)tesla:(FMTeslaLayoutView *)tesla didCreatedLayoutViewWithIndex:(NSInteger)index layoutView:(FMLayoutView *)layoutView{
NSLog(@"didCreatedLayoutViewWithIndex %ld", (long)index);
}
// 分頁滾動(dòng)到哪一頁 并返回當(dāng)前頁的layoutView
- (void)tesla:(FMTeslaLayoutView *)tesla didScrollEnd:(NSInteger)index currentLayoutView:(nonnull FMLayoutView *)layoutView{
[self.navTitleView selectWithIndex:index];
}
/// 分頁個(gè)數(shù)
- (NSInteger)numberOfScreenInTesla:(nonnull FMTeslaLayoutView *)tesla {
return 4;
}
/// 對(duì)應(yīng)頁面的view需要展示的Sections集合
- (nonnull NSMutableArray<FMLayoutBaseSection *> *)tesla:(nonnull FMTeslaLayoutView *)tesla sectionsInScreenIndex:(NSInteger)screenIndex {
return [self.sections mutableCopy];
}
/// 頭部共享的集合
- (NSArray<FMLayoutBaseSection *> *)shareSectionsInTesla:(FMTeslaLayoutView *)tesla{
return self.shareSections;
}
布局緩存還需要繼續(xù)優(yōu)化桶错,有使用問題,歡迎聯(lián)系我隨時(shí)交流胀蛮,微信:zhoufaming258, 能Star一下的話院刁,感激不盡