iOS--控制器內心獨白--我要減肥

三月不減肥,六月徒悲傷

最近接手了一個項目,當我打開控制器的時候內心是崩潰的,2000+的代碼, WTF?,(自行腦補黑人滿臉?表情包),隨后的改需求,鬼才知道我經歷了什么,所以今天來聊一聊---在使用傳統(tǒng) MVC架構的情況下,如何給控制器的簡單瘦身.

胖胖的控制器

為了節(jié)省時間,這里我用之前的開源項目來演示,精仿手工課地址源碼在最下面,現(xiàn)在我們先來看看效果圖

我的.gif

控制器
這是一個簡單的界面,采用 UICOllectionView來布局,看一下傳統(tǒng)控制器的大概分類

胖胖控制器.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];

}

數(shù)據(jù)處理

- (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];
    }];
}

數(shù)據(jù)源

#pragma mark - UICollectionView 數(shù)據(jù)源
- (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];
    }
}

從源碼可以看出,代碼量最大就是數(shù)據(jù)源和代理,所以如果我們把數(shù)據(jù)源和代理從控制中剝離出來,那么控制器的代碼數(shù)量將大大減少,接下來我們正式開始減肥計劃

瘦瘦的控制器

控制器

Snip20160820_2.png

從結構上來看,我們發(fā)現(xiàn)數(shù)據(jù)源和代理失蹤了,看看他們去哪了
Snip20160820_3.png

數(shù)據(jù)源
.h 聲明

typedef void (^CollectionViewCellConfigureBlock)(id cell, id item);

@interface GPFairArrayDataSource : NSObject <UICollectionViewDataSource>
// 給 cell 賦值的回調數(shù)組
@property (nonatomic, strong) NSArray *cellBlockArray;
// cell 的模型數(shù)組
@property (nonatomic, strong) NSArray *cellModeArray;
// cell 的唯一標示符數(shù)組
@property (nonatomic, strong) NSArray *CellIDArray;
// 獲取當前的模型
- (id)itemAtIndexPath:(NSIndexPath *)indexPath modeArray:(NSArray *)modeArray;

. M 方法的具體實現(xiàn)

@interface GPFairArrayDataSource()

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


@implementation GPFairArrayDataSource

- (id)itemAtIndexPath:(NSIndexPath *)indexPath modeArray:(NSMutableArray *)modeArray
{
    return modeArray[indexPath.row];
}
#pragma mark - UIColltionView 數(shù)據(jù)源
- (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;
}

接下來,看一下控制器中如何初始化數(shù)據(jù)源

- (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;
    
}

最后,我們來看一下效果

瘦瘦的

胖胖的

效果還是不錯的,哈哈,源碼下載,感覺有用的話,給個星星唄

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,790評論 25 709
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評論 19 139
  • 今天,瀏覽了冰葉草的《印象中橋》,感覺文筆細膩,身臨其境,美美地逛了一遍南川中橋。生活不缺美,缺的是發(fā)現(xiàn)美...
    三鑫道家養(yǎng)生閱讀 200評論 0 0
  • 蘇州觀前街,是蘇州著名的商業(yè)街。每次來蘇州,都會到觀前街逛逛,感受一下這里的商業(yè)氣息,挖掘隱藏于現(xiàn)代中的古樸。 前...
    鐵嫵閱讀 1,458評論 57 31
  • 寶桂閱讀 270評論 0 0

友情鏈接更多精彩內容