iOS Collection程序征服iOS

iOS--控制器内心独白--我要减肥

2016-08-20  本文已影响978人  呆子是只喵

三月不减肥,六月徒悲伤

最近接手了一个项目,当我打开控制器的时候内心是崩溃的,2000+的代码, WTF?,(自行脑补黑人满脸?表情包),随后的改需求,鬼才知道我经历了什么,所以今天来聊一聊---在使用传统 MVC架构的情况下,如何给控制器的简单瘦身.

胖胖的控制器

为了节省时间,这里我用之前的开源项目来演示,精仿手工课地址源码在最下面,现在我们先来看看效果图

我的.gif

控制器
这是一个简单的界面,采用 UICOllectionView来布局,看一下传统控制器的大概分类

胖胖控制器.png
首先是初始化方法
  - (instancetype)init
{
    // 流水布局
    UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
    layout.sectionInset = UIEdgeInsetsMake(10, 10, 10, 10);
    return [self initWithCollectionViewLayout:layout];
}
#pragma mark - 初始化方法
- (void)regisCell
{
    [self.collectionView registerNib:[UINib nibWithNibName:NSStringFromClass([GPFairHotCell class]) bundle:nil] forCellWithReuseIdentifier:fariId];
    [self.collectionView registerNib:[UINib nibWithNibName:NSStringFromClass([GPFairBestCell class]) bundle:nil] forCellWithReuseIdentifier:fariBestId];
    [self.collectionView registerNib:[UINib nibWithNibName:NSStringFromClass([GPFariTopicBestCell class]) bundle:nil] forCellWithReuseIdentifier:fariTopicBestId];
    [self.collectionView registerNib:[UINib nibWithNibName:NSStringFromClass([GPFariTopicCell class]) bundle:nil] forCellWithReuseIdentifier:fariTopicId];
    
     [self.collectionView registerNib:[UINib nibWithNibName:NSStringFromClass([GPFairSectionHeadView class]) bundle:nil] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:fairHeadID];

}

数据处理

- (void)loadNewData
{
    GPFariParmer *parmers = [[GPFariParmer alloc]init];
    parmers.c = @"Shiji";
    parmers.vid = @"18";
    parmers.a = self.product;
    __weak typeof(self) weakSelf = self;
    [GPFariNetwork fariDataWithParms:parmers success:^(GPFariData *fariData) {
        weakSelf.hotArray = [NSMutableArray arrayWithArray:fariData.hot];
        weakSelf.bestArray = [NSMutableArray arrayWithArray:fariData.best];
        weakSelf.topicBestArray = [NSMutableArray arrayWithArray:fariData.topicBest];
        weakSelf.topicArray = [NSMutableArray arrayWithArray:fariData.topic];
        GPFariTopicData *topicData = weakSelf.topicArray.lastObject;
        weakSelf.lastId = topicData.last_id;
        [weakSelf.collectionView reloadData];
        [weakSelf.collectionView.mj_header endRefreshing];
    } failuer:^(NSError *error) {
        [weakSelf.collectionView.mj_header endRefreshing];
        [SVProgressHUD showErrorWithStatus:@"啦啦啦,失败了"];
    }];
}
- (void)loadMoreData
{
    GPFariParmer *parmers = [[GPFariParmer alloc]init];
    parmers.c = @"Shiji";
    parmers.vid = @"18";
    parmers.last_id = self.lastId;
    parmers.a = @"topicList";
    parmers.page = self.page;
    __weak typeof(self) weakSelf = self;
    [GPFariNetwork fariMoreDataWithParms:parmers success:^(NSArray *topicDataS) {
        [weakSelf.topicArray addObjectsFromArray:topicDataS];
        [weakSelf.collectionView reloadData];
        [weakSelf.collectionView.mj_footer endRefreshing];
    } failuer:^(NSError *error) {
        [weakSelf.collectionView.mj_footer endRefreshing];
    }];
}

数据源

#pragma mark - UICollectionView 数据源
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return SectionCouton;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    NSInteger rowCount = 0;
    if (section == 0) {
        rowCount = self.hotArray.count;
    }else if (section == 1){
        rowCount = self.bestArray.count;
    }else if (section == 2){
        rowCount = self.topicBestArray.count;
    }else{
        rowCount = self.topicArray.count;
    }
    return rowCount;

}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 0){
        GPFairHotCell *hotCell = [collectionView dequeueReusableCellWithReuseIdentifier:fariId forIndexPath:indexPath];
        hotCell.hotData = self.hotArray[indexPath.row];
        return hotCell;
    }
    else if (indexPath.section == 1){
        GPFairBestCell *bestCell = [collectionView dequeueReusableCellWithReuseIdentifier:fariBestId forIndexPath:indexPath];
        bestCell.bestData = self.bestArray[indexPath.row];
        return bestCell;
        }
    else if (indexPath.section == 2){
        GPFariTopicBestCell *topicBestCell = [collectionView dequeueReusableCellWithReuseIdentifier:fariTopicBestId forIndexPath:indexPath];
        topicBestCell.picStr = self.topicBestArray[indexPath.row];
        return topicBestCell;
    }else{
        GPFariTopicCell *topicCell = [collectionView dequeueReusableCellWithReuseIdentifier:fariTopicId forIndexPath:indexPath];
        topicCell.topicData = self.topicArray[indexPath.row];
        return topicCell;
    }
    return nil;
}
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
    GPFairSectionHeadView *headView = headView = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:fairHeadID forIndexPath:indexPath];
    
    if (indexPath.section == 1) {
        headView.titleStr = @"每日特价";
        headView.subtitleStr = @"每日10:00更新";
    }else if (indexPath.section == 2){
        headView.titleStr = @"精选专题";
        headView.subtitleStr = @"更多";
    }
    return headView;
}

代理

#pragma mark - UICollectionView 布局
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
    CGSize size = CGSizeZero;
    CGFloat W = 0;
    if (indexPath.section == 0) {
        W = SCREEN_WIDTH * 0.2;
        size = CGSizeMake(W, W * 1.4);
    }else if (indexPath.section == 1){
        W = SCREEN_WIDTH * 0.27;
        size = CGSizeMake(W, W * 2);
    }else if (indexPath.section == 2){
        W = SCREEN_WIDTH * 0.27;
        size = CGSizeMake(W, W);
    }else{
        W = SCREEN_WIDTH * 0.94;
        size = CGSizeMake(W, W * 0.6);
    }
    return size;
}
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section{
    CGSize size = CGSizeZero;
    if (section == 1) {
        size = CGSizeMake(SCREEN_WIDTH, GPTitlesViewH);
    }else if (section == 2){
        size = CGSizeMake(SCREEN_WIDTH, GPTitlesViewH);
    }
    return size;
}
#pragma mark - UICollectionView 代理
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 0) {
        if (indexPath.row == 2) {
            GPWebViewController *webVC = [UIStoryboard storyboardWithName:NSStringFromClass([GPWebViewController class]) bundle:nil].instantiateInitialViewController;
            webVC.hotData = self.hotArray[indexPath.row];
            [self.navigationController pushViewController:webVC animated:YES];
        }else{
            GPTabBarController *tabVc = [[GPTabBarController alloc]init];
            tabVc.selectedIndex = 1;
            [UIApplication sharedApplication].keyWindow.rootViewController = tabVc;
        }
    }
    else if (indexPath.section == 1){
        XWCoolAnimator *animator = [XWCoolAnimator xw_animatorWithType:XWCoolTransitionAnimatorTypePortal];
        GPMainWebController *webVc = [UIStoryboard storyboardWithName:NSStringFromClass([GPMainWebController class]) bundle:nil].instantiateInitialViewController;
        webVc.bestData = self.bestArray[indexPath.row];
        [self xw_presentViewController:webVc withAnimator:animator];
    }
    else if (indexPath.section == 2){
        GPTopicListController *topListVc = [[GPTopicListController alloc]init];
        [self.navigationController pushViewController:topListVc animated:YES];
    }
    else {
        XWCoolAnimator *animator = [XWCoolAnimator xw_animatorWithType:XWCoolTransitionAnimatorTypePortal];
        GPMainWebController *webVc = [UIStoryboard storyboardWithName:NSStringFromClass([GPMainWebController class]) bundle:nil].instantiateInitialViewController;
        webVc.topicData = self.topicArray[indexPath.row];
        [self xw_presentViewController:webVc withAnimator:animator];
    }
}

从源码可以看出,代码量最大就是数据源和代理,所以如果我们把数据源和代理从控制中剥离出来,那么控制器的代码数量将大大减少,接下来我们正式开始减肥计划

瘦瘦的控制器

控制器

Snip20160820_2.png
从结构上来看,我们发现数据源和代理失踪了,看看他们去哪了
Snip20160820_3.png
数据源
.h 声明
typedef void (^CollectionViewCellConfigureBlock)(id cell, id item);

@interface GPFairArrayDataSource : NSObject <UICollectionViewDataSource>
// 给 cell 赋值的回调数组
@property (nonatomic, strong) NSArray *cellBlockArray;
// cell 的模型数组
@property (nonatomic, strong) NSArray *cellModeArray;
// cell 的唯一标示符数组
@property (nonatomic, strong) NSArray *CellIDArray;
// 获取当前的模型
- (id)itemAtIndexPath:(NSIndexPath *)indexPath modeArray:(NSArray *)modeArray;

. M 方法的具体实现

@interface GPFairArrayDataSource()

@property (nonatomic, copy) CollectionViewCellConfigureBlock configureCellBlock;
@end


@implementation GPFairArrayDataSource

- (id)itemAtIndexPath:(NSIndexPath *)indexPath modeArray:(NSMutableArray *)modeArray
{
    return modeArray[indexPath.row];
}
#pragma mark - UIColltionView 数据源
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return self.cellModeArray.count;
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    NSArray *rowArrayCount = self.cellModeArray[section];
    return rowArrayCount.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    UICollectionViewCell *cell = nil;
    NSString *cellIdentifier = self.CellIDArray[indexPath.section];
    NSArray *dataArray = self.cellModeArray[indexPath.section];
    CollectionViewCellConfigureBlock block = self.cellBlockArray[indexPath.section];
    cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
    id item = [self itemAtIndexPath:indexPath modeArray:dataArray];
    block(cell,item);
    return cell;
}
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
    GPFairSectionHeadView *headView = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"FairHeadView" forIndexPath:indexPath];
    
    if (indexPath.section == 1) {
        headView.titleStr = @"每日特价";
        headView.subtitleStr = @"每日10:00更新";
    }else if (indexPath.section == 2){
        headView.titleStr = @"精选专题";
        headView.subtitleStr = @"更多";
    }
    return headView;
}

接下来,看一下控制器中如何初始化数据源

- (void)setupCollectionView
{
    CollectionViewCellConfigureBlock configureHotCell = ^(GPFairHotCell *hotCell,GPFariHotData *hotData){
        [hotCell configureForData:hotData];
    };
    CollectionViewCellConfigureBlock configureBestCell = ^(GPFairBestCell *bestCell,GPFariBestData *BestData){
        [bestCell configureForData:BestData];
    };
    CollectionViewCellConfigureBlock configureTopicBestCell = ^(GPFariTopicBestCell *TopicBestCell,NSString *picStr){
        [TopicBestCell configureForData:picStr];
    };
    CollectionViewCellConfigureBlock configureTopicCell = ^(GPFariTopicCell *topicCell,GPFariTopicData *topicData){
        [topicCell configureForData:topicData];
    };
    self.fairDataSource = [[GPFairArrayDataSource alloc]init];
    self.fairDataSource.cellModeArray = @[self.hotArray,self.bestArray,self.topicBestArray,self.topicArray];
    self.fairDataSource.CellIDArray = @[fariId,fariBestId,fariTopicBestId,fariTopicId];
    self.fairDataSource.cellBlockArray = @[configureHotCell,configureBestCell,configureTopicBestCell,configureTopicCell];
    self.collectionView.dataSource = self.fairDataSource;
    
}

最后,我们来看一下效果

瘦瘦的
胖胖的

效果还是不错的,哈哈,源码下载,感觉有用的话,给个星星呗

上一篇下一篇

猜你喜欢

热点阅读