美文网首页iOS Collection程序征服iOS
iOS--控制器内心独白--我要减肥

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

作者: 呆子是只喵 | 来源:发表于2016-08-20 14:45 被阅读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;
        
    }
    

    最后,我们来看一下效果

    瘦瘦的
    胖胖的

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

    相关文章

      网友评论

      • 奋斗的DevAmos:还可以继续瘦身,还是有点胖
        呆子是只喵:@flyme1awqewe 求指点求带飞:smile::smile:
      • 如果丶N:感谢分享。回去在看😌😌
      • JackMengJin:下载demo,一运行首先报了3个错
        JackMengJin:@我是小菜鸟 有啥不好意思的,是我的问题,我没有更新cocoaPods- - :stuck_out_tongue_closed_eyes:
        呆子是只喵:@JackMengstan 不好意思啊,你可以重新拉一下代码,并更新一下cocoaPods;或者手动把第三方库添加一下就可以了
        呆子是只喵:@JackMengstan 报啥错?我这边没事,是不是环境问题?
      • 冰山爱美丽:每次分享都受益匪浅。谢谢楼主~:kissing_heart:
      • 2ede4a8a7da0:不错!关注你了!想你学习
        呆子是只喵:@iOS设备 互相学习互相学习

      本文标题:iOS--控制器内心独白--我要减肥

      本文链接:https://www.haomeiwen.com/subject/rolisttx.html