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

三月不减肥,六月徒悲伤

最近接手了一个项目,当我打开控制器的时候内心是崩溃的,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;
    
}

最后,我们来看一下效果

瘦瘦的

胖胖的

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,790评论 25 707
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,633评论 18 139
  • 今天,浏览了冰叶草的《印象中桥》,感觉文笔细腻,身临其境,美美地逛了一遍南川中桥。生活不缺美,缺的是发现美...
    三鑫道家养生阅读 174评论 0 0
  • 苏州观前街,是苏州著名的商业街。每次来苏州,都会到观前街逛逛,感受一下这里的商业气息,挖掘隐藏于现代中的古朴。 前...
    铁妩阅读 1,309评论 57 31
  • 宝桂阅读 250评论 0 0