iOS 做一個動態(tài)配置的大首頁

對于電商App來說,首頁一般都是一個多個內(nèi)容聚合的頁面旭蠕。整體是列表但是里面內(nèi)容特別雜停团。所以寫代碼的時候就要考慮邏輯要清晰旷坦,還要對類型的擴(kuò)展要容易。
下面根據(jù)我18年寫的一個代碼說下這個事(主要是需求更新這部分代碼沒用了佑稠,去掉前留個紀(jì)念)秒梅。

先看下效果:
May-15-2023 16-58-25.gif

說一下這個需求,因?yàn)闀r間有點(diǎn)長記得不是很清楚了舌胶,就大致說下番电,頭試圖,cell辆琅,尾視圖都有多種樣式漱办。根據(jù)相鄰兩個cell的樣式不同間距也可能不同。

實(shí)現(xiàn)方案

整體結(jié)構(gòu):

頁面整體就是一個collectionView婉烟,每一條后端數(shù)據(jù)都對應(yīng)一個section娩井,這樣做的目的:1每一條數(shù)據(jù)都可能攜帶頭部信息和尾部信息(不攜帶頭部尾部時可以拼接在一起),2可能存在有二維數(shù)據(jù)的情況

1UI上拼接顯示:
image.png

2:二維的數(shù)據(jù):
image.png

代碼實(shí)現(xiàn)

然后就是collectionView的代碼的寫法問題了似袁。整體來看大的結(jié)構(gòu)就是抽象工廠加策略
一洞辣,我寫了一個管理類通過管理類現(xiàn)實(shí)cell的代理,把動態(tài)樓層(下面我們就這么叫吧)相關(guān)的邏輯拿了出來昙衅。只放了部分代碼主要講解思路扬霜。
調(diào)用部分

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
    //動態(tài)模塊section下的item
    KFZShopHomeCardsModel * cards = [_dataModel.cardsModel.localCardsList objectAtIndexCheck:section];
    return [KFZMainPageModuleCreater moduleItemCountWithModel:cards];
}

- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    //動態(tài)模塊創(chuàng)建
    KFZShopHomeCardsModel * cards = [_dataModel.cardsModel.localCardsList objectAtIndexCheck:indexPath.section];
    return [KFZMainPageModuleCreater createCellWithModel:cards CollectionView:collectionView IndexPath:indexPath];
}

工具類內(nèi)部

@interface KFZDynamicModuleCellCeater : NSObject

//----cell
+(UICollectionViewCell *)createCellWithModel:(KFZShopHomeCardsModel *)moduleModel CollectionView:(UICollectionView *)collectionView IndexPath:(NSIndexPath *)indexPath;
+(NSInteger)moduleItemCountWithModel:(KFZShopHomeCardsModel *)moduleModel;
+(void)moduleItemClickWithModel:(KFZShopHomeCardsModel *)moduleModel IndexPath:(NSIndexPath *)indexPath;
+(CGSize)moduleItemSizeWithModel:(KFZShopHomeCardsModel *)moduleModel IndexPath:(NSIndexPath *)indexPath;

//----headerView
+(UICollectionReusableView *)createHeaderViewWithModel:(KFZShopHomeCardsModel *)moduleModel CollectionView:(UICollectionView *)collectionView IndexPath:(NSIndexPath *)indexPath;
+(CGSize)moduleIHeaderSizeWithModel:(KFZShopHomeCardsModel *)moduleModel;
+(UICollectionReusableView *)defautCollectionReusableViewCollectionView:(UICollectionView *)collectionView IndexPath:(NSIndexPath *)indexPath;

//----footerView
+(UICollectionReusableView *)createFooterViewWithModel:(KFZShopHomeCardsModel *)moduleModel CollectionView:(UICollectionView *)collectionView IndexPath:(NSIndexPath *)indexPath;
+(CGSize)moduleIFooterSizeWithModel:(KFZShopHomeCardsModel *)moduleModel;
+(UICollectionReusableView *)defautCollectionFooterViewCollectionView:(UICollectionView *)collectionView IndexPath:(NSIndexPath *)indexPath;
+(CGFloat)sameModuleSpaceHeight:(CardsType)cardType;


//----sectionLayout section各種間距
+(UIEdgeInsets)sectionInsetsWithModel:(KFZShopHomeCardsModel *)moduleModel;
+(CGFloat)sectionLineSpacingWithModel:(KFZShopHomeCardsModel *)moduleModel;
+(CGFloat)sectionItemSpacingWithModel:(KFZShopHomeCardsModel *)moduleModel;

//---regist
+(void)registAllClassIdentifirsCollectionView:(UICollectionView *)collectView;

@end
@implementation KFZDynamicModuleCellCeater
#pragma mark - 模塊下 Cell

/**
 根據(jù) 模塊的類型 創(chuàng)建cell
 
 @param moduleModel 模塊數(shù)據(jù)
 @param collectionView 當(dāng)前的collectionView
 @param indexPath 當(dāng)前indexPath
 @return 創(chuàng)建的cell
 */
+(UICollectionViewCell *)createCellWithModel:(KFZShopHomeCardsModel *)moduleModel CollectionView:(UICollectionView *)collectionView IndexPath:(NSIndexPath *)indexPath{
    return [[KFZDynamicModuleConfig factoryConfig:moduleModel.winddowShowType] createCellWithModel:moduleModel CollectionView:collectionView IndexPath:indexPath];
}

/**
 item的size
 
 @param moduleModel 數(shù)據(jù)
 @param indexPath 位置
 @return 計(jì)算出的size
 */
+(CGSize)moduleItemSizeWithModel:(KFZShopHomeCardsModel *)moduleModel IndexPath:(NSIndexPath *)indexPath{
    return [[KFZDynamicModuleConfig factoryConfig:moduleModel.winddowShowType] moduleItemSizeWithModel:moduleModel IndexPath:indexPath];
}

/**
 item點(diǎn)擊方法
 */
+(void)moduleItemClickWithModel:(KFZShopHomeCardsModel *)moduleModel IndexPath:(NSIndexPath *)indexPath{
    [[KFZDynamicModuleConfig factoryConfig:moduleModel.winddowShowType] moduleItemClickWithModel:moduleModel IndexPath:indexPath];
}

/**
 每個模塊item的個數(shù)
 */
+(NSInteger)moduleItemCountWithModel:(KFZShopHomeCardsModel *)moduleModel{
    return [[KFZDynamicModuleConfig factoryConfig:moduleModel.winddowShowType]moduleItemCountWithModel:moduleModel];
}

#pragma mark - 模塊中的各種間距

+(UIEdgeInsets)sectionInsetsWithModel:(KFZShopHomeCardsModel *)moduleModel{
    return [[KFZDynamicModuleConfig factoryConfig:moduleModel.winddowShowType]sectionInsetsWithModel:moduleModel];
}

+(CGFloat)sectionLineSpacingWithModel:(KFZShopHomeCardsModel *)moduleModel{
    return [[KFZDynamicModuleConfig factoryConfig:moduleModel.winddowShowType]sectionLineSpacingWithModel:moduleModel];
}

+(CGFloat)sectionItemSpacingWithModel:(KFZShopHomeCardsModel *)moduleModel{
    return [[KFZDynamicModuleConfig factoryConfig:moduleModel.winddowShowType]sectionItemSpacingWithModel:moduleModel];
}


#pragma mark - 模塊下 頭試圖

+(UICollectionReusableView *)createHeaderViewWithModel:(KFZShopHomeCardsModel *)moduleModel CollectionView:(UICollectionView *)collectionView IndexPath:(NSIndexPath *)indexPath{
    return [[KFZDynamicModuleConfig headerFactoryConfigWithHeaderStr:moduleModel.sectionHeaderStyleName]createHeaderViewWithModel:moduleModel CollectionView:collectionView IndexPath:indexPath];
}

+(CGSize)moduleIHeaderSizeWithModel:(KFZShopHomeCardsModel *)moduleModel{
    return [[KFZDynamicModuleConfig headerFactoryConfigWithHeaderStr:moduleModel.sectionHeaderStyleName]moduleIHeaderSizeWithModel:moduleModel];
}

/**
 默認(rèn)透明頭試圖
 */
+(UICollectionReusableView *)defautCollectionReusableViewCollectionView:(UICollectionView *)collectionView IndexPath:(NSIndexPath *)indexPath{
    UICollectionReusableView * headerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:NSStringFromClass([UICollectionReusableView class]) forIndexPath:indexPath];
    headerView.backgroundColor = [UIColor clearColor];
    return headerView;
}

#pragma mark - 模塊下 尾視圖 *** 模塊之前的間隔 由這里控制

+(UICollectionReusableView *)createFooterViewWithModel:(KFZShopHomeCardsModel *)moduleModel CollectionView:(UICollectionView *)collectionView IndexPath:(NSIndexPath *)indexPath{
    if (moduleModel.isHaveFooter) {
        KFZShopHomeAreaFooterView * footer = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:NSStringFromClass([KFZShopHomeAreaFooterView class]) forIndexPath:indexPath];
        if ([moduleModel.showMoreType isEqualToString:@"1"]) {
            footer.footerType = KFZShopHomeFooterType_LookMore;
        }else{
            footer.footerType = KFZShopHomeFooterType_FreshList;
        }
        footer.sectionIndex = indexPath.section;
        footer.sectionModel = moduleModel;
        
        __weak typeof(collectionView)wkCollection = collectionView;
        footer.selfBeClick = ^(NSInteger section) {
            [wkCollection reloadSections:[NSIndexSet indexSetWithIndex:section]];
        };
        return footer;
    }
    return [self defautCollectionFooterViewCollectionView:collectionView IndexPath:indexPath];
}

+(CGSize)moduleIFooterSizeWithModel:(KFZShopHomeCardsModel *)moduleModel{
    if (moduleModel.isHaveFooter) {
        KFZShopHomeCardsModel * nextModel  = moduleModel.nextLink;
        if (nil != nextModel && (nextModel.HaveHeaderTitle || nextModel.HaveHeaderScran)) {
            return CGSizeMake(DEF_SCREEN_WIDTH, 70 + 10);
        }
        return CGSizeMake(DEF_SCREEN_WIDTH, 70);
    }else{
        
        KFZShopHomeCardsModel * nextModel = moduleModel.nextLink;
        
        //要判斷兩個模塊之間的距離 所以取值上保證不是最后一個模塊
        if (nil != nextModel) {
            
            //如果下一個模塊有頭試圖的話 算是兩個模塊了 當(dāng)前模塊向下的間隔應(yīng)該是47
            if (nextModel.HaveHeaderTitle || nextModel.HaveHeaderScran || nextModel.HaveHeaderLabels) {
                return CGSizeMake(DEF_SCREEN_WIDTH, 47);
            }
            
            //如果沒有頭試圖的時候
            
            //判斷兩個模塊是否是一種類型
            if (moduleModel.winddowShowType == nextModel.winddowShowType) {
                return CGSizeMake(DEF_SCREEN_WIDTH, [self sameModuleSpaceHeight:moduleModel.winddowShowType]);
            }
            
            //兩種模塊不是一種類型
            
            //兩種模塊不是一種類型   但是兩種模塊分別是兩格(twoCard)和三格(threeCard)
            if ((moduleModel.winddowShowType == CardsType_twoCard || moduleModel.winddowShowType == CardsType_threeCard) && (nextModel.winddowShowType == CardsType_twoCard || nextModel.winddowShowType == CardsType_threeCard)) {
                return CGSizeMake(DEF_SCREEN_WIDTH, 3);
            }
            //兩種模塊不是一種類型   但是兩種模塊分別是一個高(OneCard_height)和一格矮(OneCard)
            else if ((moduleModel.winddowShowType == CardsType_OneCard_height || moduleModel.winddowShowType == CardsType_OneCard) && (nextModel.winddowShowType == CardsType_OneCard_height || nextModel.winddowShowType == CardsType_OneCard)) {
                return CGSizeMake(DEF_SCREEN_WIDTH, 3);
            }
            else{
                return CGSizeMake(DEF_SCREEN_WIDTH, 47);
            }
        }
        
        //最后一個模塊的邏輯
        
        //如果是猜你喜歡 下面會有一個查看更多的尾試圖所以要把間距改為0
        if (moduleModel.winddowShowType == CardsType_GuessYouLike) {
            return CGSizeMake(DEF_SCREEN_WIDTH, 0);;
        }
        
    }
    return CGSizeMake(DEF_SCREEN_WIDTH, 0);
}

/**
 默認(rèn)透明尾試圖
 */
+(UICollectionReusableView *)defautCollectionFooterViewCollectionView:(UICollectionView *)collectionView IndexPath:(NSIndexPath *)indexPath{
    UICollectionReusableView * headerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:NSStringFromClass([UICollectionReusableView class]) forIndexPath:indexPath];
    headerView.backgroundColor = [UIColor clearColor];
    return headerView;
}

/**
 上下兩個是同類型時的間距
 */
+(CGFloat)sameModuleSpaceHeight:(CardsType)cardType{
    
    switch (cardType) {
        case CardsType_OneCard_height:{
            return 3;
        }
        case CardsType_OneCard:{
            return 3;
        }
        case CardsType_twoCard:{
            return 3;
        }
        case CardsType_threeCard:{
            return 3;
        }
        case CardsType_preciousBook:{
            return 25;
        }
        case CardsType_goodBook:{
            return 25;
        }
        case CardsType_goodShop:{
            return 15;
        }
        case CardsType_GuessYouLike:{
            return 10;
        }
        case CardsType_BookList:{
            return 47;
        }
        default:
            return 47;
    }
}



#pragma mark - 注冊方法

/**
 像當(dāng)前的collectionView注冊cell和頭尾試圖 --- (一點(diǎn)不好 所有的都要注冊現(xiàn)有的全部類型)
 
 @param collectView 當(dāng)前的collectionView
 */
+(void)registAllClassIdentifirsCollectionView:(UICollectionView *)collectView{
    [collectView registerClass:[KFZShopThreeCardCell class] forCellWithReuseIdentifier:NSStringFromClass([KFZShopThreeCardCell class])];
    [collectView registerClass:[KFZShopTwoCardCell class] forCellWithReuseIdentifier:NSStringFromClass([KFZShopTwoCardCell class])];
    [collectView registerClass:[KFZOneHeightCardCell class] forCellWithReuseIdentifier:NSStringFromClass([KFZOneHeightCardCell class])];
    [collectView registerClass:[KFZOneLowCardCell class] forCellWithReuseIdentifier:NSStringFromClass([KFZOneLowCardCell class])];
    [collectView registerClass:[KFZImageTitlePrise_GoodsCell class] forCellWithReuseIdentifier:NSStringFromClass([KFZImageTitlePrise_GoodsCell class])];
    [collectView registerClass:[KFZImageTitleAuthorPrise_GoodsCell class] forCellWithReuseIdentifier:NSStringFromClass([KFZImageTitleAuthorPrise_GoodsCell class])];
    [collectView registerClass:[KFZShopHomeAreaShopCell class] forCellWithReuseIdentifier:NSStringFromClass([KFZShopHomeAreaShopCell class])];
    [collectView registerClass:[KFZGuessYourLikeCell class] forCellWithReuseIdentifier:NSStringFromClass([KFZGuessYourLikeCell class])];
    [collectView registerClass:[KFZChannelBoolListCell class] forCellWithReuseIdentifier:NSStringFromClass([KFZChannelBoolListCell class])];
    [collectView registerClass:[KFZISBNHorizontalScrollCell class] forCellWithReuseIdentifier:NSStringFromClass([KFZISBNHorizontalScrollCell class])];
    [collectView registerClass:[KFZISBNTableStyleCell class] forCellWithReuseIdentifier:NSStringFromClass([KFZISBNTableStyleCell class])];
    [collectView registerClass:[KFZGoodsHorizontalScrollCell class] forCellWithReuseIdentifier:NSStringFromClass([KFZGoodsHorizontalScrollCell class])];
    [collectView registerClass:[KFZAuctionHorizontalScrollCell class] forCellWithReuseIdentifier:NSStringFromClass([KFZAuctionHorizontalScrollCell class])];
    [collectView registerClass:[KFZGoodsTableStyleCell class] forCellWithReuseIdentifier:NSStringFromClass([KFZGoodsTableStyleCell class])];
    [collectView registerClass:[KFZAuctionSpecialHorizontalScrollCell class] forCellWithReuseIdentifier:NSStringFromClass([KFZAuctionSpecialHorizontalScrollCell class])];
    [collectView registerClass:[KFZAuctionAdvertisementCell class] forCellWithReuseIdentifier:NSStringFromClass([KFZAuctionAdvertisementCell class])];
    
    [collectView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:NSStringFromClass([UICollectionReusableView class])];
    [collectView registerClass:[KFZShopHomeAreaFooterView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:NSStringFromClass([KFZShopHomeAreaFooterView class])];
    [collectView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:NSStringFromClass([UICollectionReusableView class])];
    [collectView registerClass:[KFZOnlyTitleHeaderView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:NSStringFromClass([KFZOnlyTitleHeaderView class])];
    [collectView registerClass:[KFZOnlyScreenHeaderView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:NSStringFromClass([KFZOnlyScreenHeaderView class])];
    [collectView registerClass:[KFZTitleAndScreenHeaderView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:NSStringFromClass([KFZTitleAndScreenHeaderView class])];
    [collectView registerClass:[KFZOnlyLabelsHeaderView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:NSStringFromClass([KFZOnlyLabelsHeaderView class])];
    [collectView registerClass:[KFZTitleAndLabelsHeaderView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:NSStringFromClass([KFZTitleAndLabelsHeaderView class])];
    
}
@end

二,可以看到上面代碼KFZDynamicModuleConfig這個算是一個策略選擇不過我內(nèi)部是用映射是生成對應(yīng)的工廠的而涉。(正常寫的話肯定是先寫出工廠然后才有這個著瓶,不過看代碼正好是可以按照這個關(guān)聯(lián)性去看)

@interface KFZDynamicModuleConfig : NSObject

/**
 根據(jù) 模塊類型枚舉的值 來取工廠類

 @return 返回對應(yīng)的工廠類
 */
+(KFZDynamicModuleCellFactory *)factoryConfig:(CardsType)type;

/**
 根據(jù) 模塊類型枚舉的值 來取工廠類
 
 @return 返回對應(yīng)的工廠類
 */
+(KFZDynamicModuleHeaderFactory *)headerFactoryConfig:(CardsHeadType)type;

/**
 根據(jù) 頭試圖描述字符串 來取工廠類
 
 @return 返回對應(yīng)的工廠類
 */
+(KFZDynamicModuleHeaderFactory *)headerFactoryConfigWithHeaderStr:(NSString *)headerStr;


/** 通知-通知頻道頁面刷新(ps:主要做換一換功能只是在當(dāng)前頁面的一個通知,頁面不顯示就移除) */
FOUNDATION_EXPORT NSString *const ChannelController_FreshSection;

@end
···
···
#import "KFZDynamicModuleConfig.h"

@implementation KFZDynamicModuleConfig
+(KFZDynamicModuleCellFactory *)factoryConfig:(CardsType)type{
    NSArray * list = @[@"KFZOneCardHeightFactory"
                       ,@"KFZOneCardLowFactory"
                       ,@"KFZTwoCardFactory"
                       ,@"KFZThreeCardFactory"
                       ,@"KFZVerticalBookFactory"
                       ,@"KFZVerticalISBNFactory"
                       ,@"KFZVerticalShopFactory"
                       ,@"KFZGuessYouLikeGoodsFactory"
                       ,@"KFZHorizontalBookListFactory"
                       ,@"KFZISBNHorizontalScrollFactory"
                       ,@"KFZISBNTableStyleFactory"
                       ,@"KFZGoodsHorizontalScrollFactory"
                       ,@"KFZAuctionHorizontalScrollFactory"
                       ,@"KFZGoodsTableStyleFactory"
                       ,@"KFZAuctionSpecialHorizontalScrollFactory"
                       ,@"KFZAuctionAdvertisementFactory"];
    NSString * className = list[type];
    Class class = NSClassFromString(className);
    KFZDynamicModuleCellFactory * factory = [class new];
    return factory;
}

+(KFZDynamicModuleHeaderFactory *)headerFactoryConfig:(CardsHeadType)type{
    NSArray * list = @[@"KFZPureColor_WhiteHeaderFactory"
                       ,@"KFZOnlyTitleHeaderFactory"
                       ,@"KFZOnlyScreenHeaderFactory"
                       ,@"KFZTitleAndScreenHeaderFactory"
                       ,@"KFZOnlyLabelsHeaderFactory"
                       ,@"KFZTitleAndLabelsHeaderFactory"];
    NSString * className = list[type];
    Class class = NSClassFromString(className);
    KFZDynamicModuleHeaderFactory * factory = [class new];
    return factory;
}

+(KFZDynamicModuleHeaderFactory *)headerFactoryConfigWithHeaderStr:(NSString *)headerStr{
    NSDictionary * list = @{@"haveTitlehaveScranhaveLabels":@"KFZTitleAndScreenHeaderFactory",//=
                            @"haveTitlehaveScrannoLabels":@"KFZTitleAndScreenHeaderFactory",
                            @"haveTitlenoScranhaveLabels":@"KFZTitleAndLabelsHeaderFactory",
                            @"haveTitlenoScrannoLabels":@"KFZOnlyTitleHeaderFactory",
                            @"noTitlehaveScranhaveLabels":@"KFZOnlyScreenHeaderFactory",//=
                            @"noTitlehaveScrannoLabels":@"KFZOnlyScreenHeaderFactory",
                            @"noTitlenoScranhaveLabels":@"KFZOnlyLabelsHeaderFactory",
                            @"noTitlenoScrannoLabels":@"KFZPureColor_WhiteHeaderFactory",
                            
                            };
    NSString * className = list[headerStr];
    Class class = NSClassFromString(className);
    KFZDynamicModuleHeaderFactory * factory = [class new];
    return factory;
}

NSString *const ChannelController_FreshSection = @"com.Kongfz.ChannelController_FreshSection";//通知-通知頻道頁面刷新

@end

這里面的一些枚舉啼县,其實(shí)就是后端標(biāo)識的數(shù)據(jù)類型材原,我這面轉(zhuǎn)成枚舉了。
第三季眷,就是多個工廠的實(shí)現(xiàn)了余蟹。在KFZDynamicModuleConfig可以看見我返回工廠時的類是KFZDynamicModuleCellFactory這里我是使用基類的方式代替了協(xié)議了。
這里我就舉個簡單的例子吧子刮,就上面一橫行兩個圖片的那種威酒。

@interface KFZTwoCardFactory : KFZDynamicModuleCellFactory
@end
@implementation KFZTwoCardFactory
//----cell
-(UICollectionViewCell *)createCellWithModel:(KFZShopHomeCardsModel *)moduleModel CollectionView:(UICollectionView *)collectionView IndexPath:(NSIndexPath *)indexPath{
    KFZShopTwoCardCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([KFZShopTwoCardCell class]) forIndexPath:indexPath];
    cell.model = moduleModel;
    return cell;
}
-(NSInteger)moduleItemCountWithModel:(KFZShopHomeCardsModel *)moduleModel{
    return 1;
}
-(void)moduleItemClickWithModel:(KFZShopHomeCardsModel *)moduleModel IndexPath:(NSIndexPath *)indexPath{
    //cellb內(nèi)部做跳轉(zhuǎn)了
}
-(CGSize)moduleItemSizeWithModel:(KFZShopHomeCardsModel *)moduleModel IndexPath:(NSIndexPath *)indexPath{
    return CGSizeMake(DEF_SCREEN_WIDTH - 30, 66*SHOPHOMEAREA_WIDTH_RATIO);
}

//----sectionLayout section各種間距
-(UIEdgeInsets)sectionInsetsWithModel:(KFZShopHomeCardsModel *)moduleModel{
    return UIEdgeInsetsMake(0, 15, 0, 15);
}
-(CGFloat)sectionLineSpacingWithModel:(KFZShopHomeCardsModel *)moduleModel{
    return 25;
}
-(CGFloat)sectionItemSpacingWithModel:(KFZShopHomeCardsModel *)moduleModel{
    return 15*SHOPHOMEAREA_WIDTH_RATIO;
}
@end

整體結(jié)構(gòu)就這樣說完了,其實(shí)也不是很復(fù)雜是不是挺峡。最后附加一個我這里類型的截圖:


image.png

打完收工!!!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末葵孤,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子沙郭,更是在濱河造成了極大的恐慌佛呻,老刑警劉巖裳朋,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件病线,死亡現(xiàn)場離奇詭異吓著,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)送挑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進(jìn)店門绑莺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人惕耕,你說我怎么就攤上這事纺裁。” “怎么了司澎?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵欺缘,是天一觀的道長。 經(jīng)常有香客問我挤安,道長谚殊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任蛤铜,我火速辦了婚禮嫩絮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘围肥。我一直安慰自己剿干,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布穆刻。 她就那樣靜靜地躺著置尔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪氢伟。 梳的紋絲不亂的頭發(fā)上撰洗,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天,我揣著相機(jī)與錄音腐芍,去河邊找鬼差导。 笑死,一個胖子當(dāng)著我的面吹牛猪勇,可吹牛的內(nèi)容都是我干的设褐。 我是一名探鬼主播,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼泣刹,長吁一口氣:“原來是場噩夢啊……” “哼助析!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起椅您,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤外冀,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后掀泳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體雪隧,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡西轩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了脑沿。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片藕畔。...
    茶點(diǎn)故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖庄拇,靈堂內(nèi)的尸體忽然破棺而出注服,到底是詐尸還是另有隱情,我是刑警寧澤措近,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布溶弟,位于F島的核電站,受9級特大地震影響瞭郑,放射性物質(zhì)發(fā)生泄漏可很。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一凰浮、第九天 我趴在偏房一處隱蔽的房頂上張望我抠。 院中可真熱鬧,春花似錦袜茧、人聲如沸菜拓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽纳鼎。三九已至,卻和暖如春裳凸,著一層夾襖步出監(jiān)牢的瞬間贱鄙,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工姨谷, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留逗宁,地道東北人。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓梦湘,卻偏偏與公主長得像瞎颗,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子捌议,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內(nèi)容