iOS - TableViewCell(CollectionViewCell)的工廠設(shè)計模式

一. 聲明:
在此文章中以tableView舉例, 便于描述.
二. 問題提出:
通常我們在寫一個tableView時候, 在其協(xié)議方法:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

在其中會創(chuàng)建多種cell或者從重用池中取出多種cell, 而通常使用index進行判斷, 什么時候用哪種cell, 如果這個頁面cell的種類少倒還好, 可是如果cell種類繁雜, 那么在這個協(xié)議方法中的判斷那真是非常折磨人的, 所以參照一些資料, 想出這個cell 的工廠模式.
三. 想法:
所謂的工廠模式, 咱們可以這么理解, 一個工廠就是一個加工車間, 如圖所示, 送進去原料, 在工廠中進行一系列加工處理, 然后生產(chǎn)出產(chǎn)品.

工廠模式.png

用在此處就體現(xiàn)出了面向?qū)ο蟮膬蓚€特性: 繼承和多態(tài). 我們用同樣的思維來思考cell工廠的模式, 我們需要原料, 送進CellFactory, 然后得到對應(yīng)種類的cell.
四. 思路:
同理, 通過數(shù)據(jù)轉(zhuǎn)化成Model, 再由tableViewCell呈現(xiàn)到界面給用戶(CollectionView同理).我們得知道自己需要什么, 當(dāng)然工廠的產(chǎn)品應(yīng)該是不同種類的cell, 那么他的原料也應(yīng)該是不一樣的, 那cell種類和什么東西是一一對應(yīng)的呢, 顯而易見是不同種類的model, 這樣我們基本的思路就成型了, 創(chuàng)建一個cellFactory, 放入Model, 進行處理, 生成cell


CellFactory示意圖.png

五. 實現(xiàn)過程:

  1. 第一步:創(chuàng)建基類BaseTableViewCell, 繼承于UITableViewCell,
    在BaseTableViewCell.h中聲明方法:
// 賦值方法(在父類實現(xiàn), 在子類中重寫)
-(void)setModel:(__kindof BaseModel *)model;

在BaseTableViewCell.m中實現(xiàn)方法:

-(void)setModel:(__kindof BaseModel *)model {
}
  1. 第二步:創(chuàng)建model的基類BaseModel, 繼承于NSObject
    在BaseModel.h中聲明方法
+(instancetype)modelWithDictionary:(NSDictionary *)dic;

在BaseModel.m中實現(xiàn)方法

-(void)setValue:(id)value forKey:(NSString *)key {
    [super setValue:value forKey:key];
}
-(void)setValue:(id)value forUndefinedKey:(NSString *)key {
    [super setValue:value forUndefinedKey:key];
}
-(id)valueForUndefinedKey:(NSString *)key {  
    return nil;
}
-(instancetype)initWithDictionary:(NSDictionary *)dic {
    self = [super init];
    if (self) {      
    [self setValuesForKeysWithDictionary:dic];
    }
    return self;
}
+(BaseModel *)modelWithDictionary:(NSDictionary *)dic {
    return [[self alloc] initWithDictionary:dic];
}
  1. 第三步:創(chuàng)建model: StudentModel, 繼承于BaseModel
//寫對應(yīng)的屬性, 此處為了簡單只寫了一個name
@property (nonatomic, copy) NSString *name;
  1. 第四步: 創(chuàng)建tableViewCell: StudentTableViewCell, 繼承于BaseTableViewCell
    這里為了方便直接使用xib鋪了一個Label, 并重寫B(tài)aseTableView中的賦值方法:
-(void)setModel:(StudentModel *)model {
    [super setModel:model];
    _nameLabel.text = model.name;
}
StudentTableViewCell.png
  1. 第五步: 創(chuàng)建一個工廠類, LTQCellFactory
    在LTQCellFactory.h中聲明:
+(BaseTableViewCell *)createTableViewCellWithModel:(BaseModel *)model
                                          tableView:(UITableView *)tableView;

在LTQCellFactory.m中實現(xiàn):

+(BaseTableViewCell *)createTableViewCellWithModel:(BaseModel *)model
                                          tableView:(UITableView *)tableView {
    NSString *modelName = [NSString stringWithUTF8String:object_getClassName(model)];
    NSString *classNameOfCell = [[modelName substringToIndex:modelName.length - 5] stringByAppendingString:@"TableViewCell"];
    BaseTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:classNameOfCell];
    return cell;
}
  1. 第六步:引入頭文件后,注冊Cell并在ViewController中實現(xiàn)
// 注冊StudentTableViewCell
 [_tableView registerNib:[UINib nibWithNibName:@"StudentTableViewCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"StudentTableViewCell"];
// 在tableView協(xié)議方法中實現(xiàn)
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    BaseModel *model = _dataArr[indexPath.row];
    BaseTableViewCell *cell = [LTQCellFactory createTableViewCellWithModel:(BaseModel *)model tableView:tableView];
    [cell setModel:model];
    return cell;
}

補充: 由于我自己寫的CellFactory是用model的Classname與Cell的Classname進行關(guān)聯(lián)的, 所以在給model和cell的類起名字的時候, 一定要注意, model類名一定要為XXXModel, 而對應(yīng)的Cell名一定要為XXXTableViewCell或XXXCollectionViewCell,
而在注冊的時候直接用cell的類名作為cell在重用池中的重用標(biāo)識
例如:


起名問題.png

結(jié)論: 這樣一來可以在這個dataSource的協(xié)議方法中可以節(jié)省大量的判斷和其他操作過程, 運用了繼承和多態(tài), 使得代碼更加整潔, 并且高大上了有木有, 如果有問題歡迎留言討論, 如果我寫的文章對你有幫助別忘記點個贊哦??

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末恶导,一起剝皮案震驚了整個濱河市猎醇,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖薪前,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贝乎,死亡現(xiàn)場離奇詭異,居然都是意外死亡挑童,警方通過查閱死者的電腦和手機累铅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來站叼,“玉大人,你說我怎么就攤上這事菇民【⌒ǎ” “怎么了?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵第练,是天一觀的道長阔馋。 經(jīng)常有香客問我,道長娇掏,這世上最難降的妖魔是什么呕寝? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮婴梧,結(jié)果婚禮上下梢,老公的妹妹穿的比我還像新娘。我一直安慰自己塞蹭,他們只是感情好孽江,可當(dāng)我...
    茶點故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著番电,像睡著了一般岗屏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上漱办,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天这刷,我揣著相機與錄音,去河邊找鬼娩井。 笑死暇屋,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的撞牢。 我是一名探鬼主播率碾,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼屋彪!你這毒婦竟也來了所宰?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤畜挥,失蹤者是張志新(化名)和其女友劉穎仔粥,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡躯泰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年谭羔,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片麦向。...
    茶點故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡瘟裸,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出诵竭,到底是詐尸還是另有隱情话告,我是刑警寧澤,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布卵慰,位于F島的核電站沙郭,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏裳朋。R本人自食惡果不足惜病线,卻給世界環(huán)境...
    茶點故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鲤嫡。 院中可真熱鬧送挑,春花似錦、人聲如沸泛范。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽罢荡。三九已至赡突,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間区赵,已是汗流浹背惭缰。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留笼才,地道東北人漱受。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像骡送,于是被迫代替她去往敵國和親昂羡。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,901評論 2 355

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