iOS實(shí)戰(zhàn):解耦合-UITableView模塊化開(kāi)發(fā)

本篇文章主要的目的是分享一種UITableView模塊化開(kāi)發(fā)的思路。

在開(kāi)發(fā)過(guò)程中,常常會(huì)遇到很復(fù)雜的tableview的界面,往往每一個(gè)的section都是完全不一樣的。比如這樣:

例子.png

這個(gè)界面中,每一個(gè)section都是不同的。當(dāng)需要多人去開(kāi)發(fā)這樣的界面,每個(gè)人負(fù)責(zé)一到兩個(gè)section,如何去管理大家的代碼,讓代碼互不沖突呢?

解決方法就是分模塊化開(kāi)發(fā)。大致的思路是這樣的:控制器中不寫(xiě)任何和各個(gè)section相關(guān)的代碼,只需創(chuàng)建UITableView并編寫(xiě)其相關(guān)的數(shù)據(jù)源方法。這里的每一個(gè)section對(duì)應(yīng)一個(gè)繼承自NSObjectcontrol類(lèi)。在控制器中,添加一個(gè)個(gè)control到數(shù)組controls中??蓪?code>control作為一個(gè)控制器,所有的數(shù)據(jù)獲取,邏輯處理均可在其中完成。

說(shuō)到這里,你如果看過(guò)自造輪子:YQCommonCell 簡(jiǎn)化表單視圖開(kāi)發(fā),應(yīng)該會(huì)發(fā)現(xiàn)兩者在思路上是類(lèi)似的,將section對(duì)應(yīng)模型抽離出,相關(guān)section的屬性均在模型中編寫(xiě)。

但是,目前存在兩個(gè)問(wèn)題:

1.如何將每一個(gè)section都正確的顯示在界面上?;蛘哒f(shuō),section界面設(shè)置的入口改在哪?

2.control想要刷新tableview的時(shí)候,該如何去做。


1.如何將每一個(gè)section都正確的顯示在界面上?;蛘哒f(shuō),section界面設(shè)置的入口改在哪?

在初學(xué)時(shí),遇到這種界面,第一反應(yīng)就是創(chuàng)建自定義視圖cell,在cellForRow中設(shè)置對(duì)應(yīng)的cell。這樣做的代價(jià)是所有的數(shù)據(jù)請(qǐng)求等都在控制器中完成,而現(xiàn)在要由control來(lái)完成。在control中設(shè)置一個(gè)全局屬性view,然后再去cellForRow設(shè)置?不是的。

其實(shí)方法很簡(jiǎn)單,在tableView數(shù)據(jù)源的方法cellForRow中,讓每一個(gè)control去實(shí)現(xiàn)cellForRow方法,也就是說(shuō),在control中,自行設(shè)置其對(duì)應(yīng)的sectioncell。其他的section屬性也是類(lèi)似的。

那么,可寫(xiě)個(gè)協(xié)議,我暫時(shí)命名為YQModuleResolveControlProtocol。在該協(xié)議中,設(shè)置必須實(shí)現(xiàn)的方法:

@required
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRow:(NSInteger)row;
- (CGFloat)heightForRow:(NSInteger)row;
- (NSInteger)numberOfRows;

還有可選擇實(shí)現(xiàn)的方法:

@optional
- (CGFloat)heightForHeader;
- (UIView *)viewForHeader;
- (CGFloat)heightForFooter;
- (UIView *)viewForFooter;
- (void)tableView:(UITableView *)tableView cellSelectIndexPath:(NSIndexPath *)indexPath;

只需讓每一個(gè)control遵循YQModuleResolveControlProtocol,實(shí)現(xiàn)必須實(shí)現(xiàn)的方法。

在控制器中,以cellForRow為例:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section >= self.controls.count) {
        return [[UITableViewCell alloc] init];
    }
    id <YQModuleResolveControlProtocol>control = self.controls[indexPath.section];
    if ([control respondsToSelector:@selector(tableView:cellForRow:)]) {
        return [control tableView:tableView cellForRow:indexPath.row];
    }
    return [[UITableViewCell alloc] init];
}

這樣,很完美的將代碼抽離到一個(gè)個(gè)模塊中。


2.control想要刷新tableview的時(shí)候,該如何去做。

這個(gè)問(wèn)題的本質(zhì)就是數(shù)據(jù)傳遞或事件傳遞,很簡(jiǎn)單,用代理即可。

新的協(xié)議:

@protocol YQModuleResolveControlDelegate <NSObject>
@optional
- (void)reloadControl:(id)control row:(NSInteger)row;
- (void)reloadOwnControl:(id)control;
- (void)reloadAllTableView:(UITableViewRowAnimation)animation;
@end

讓控制器遵循該協(xié)議,并實(shí)現(xiàn)(以刷新某一行為例):

#pragma mark - YQModuleResolveControlDelegate
- (void)reloadControl:(id)control row:(NSInteger)row
{
    if ([self.controls containsObject:control]) {
        NSInteger section = [self.controls indexOfObject:control];
        NSIndexPath *indexpath = [NSIndexPath indexPathForRow:row inSection:section];
        [self.tv reloadRowsAtIndexPaths:@[indexpath] withRowAnimation:UITableViewRowAnimationFade];
    }
}

這樣,就能做到control隨時(shí)主動(dòng)刷新tableView。


以上,就能做到本文最開(kāi)頭所寫(xiě)的要求,將每一個(gè)section對(duì)應(yīng)的所有代碼抽離至control。具體開(kāi)發(fā)時(shí),讓每一位開(kāi)發(fā)人員自行創(chuàng)建control即可。而ViewController將會(huì)一身輕松且不需要時(shí)常修改代碼。

順便補(bǔ)充一點(diǎn),如果想讓ViewController編寫(xiě)完后就再也不修改任何代碼,可將控制器controls添加control這一部分也抽離到分類(lèi)中,每一位開(kāi)發(fā)人員自行去分類(lèi)中添加自己的control即可。

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

相關(guān)閱讀更多精彩內(nèi)容

  • 1.ios高性能編程 (1).內(nèi)層 最小的內(nèi)層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結(jié)構(gòu)(3).初始化時(shí)...
    歐辰_OSR閱讀 30,192評(píng)論 8 265
  • 練習(xí)練習(xí)再練習(xí),觀察,臨摹。 用碎片時(shí)間,雖然每次畫(huà)時(shí)都覺(jué)得前一階段畫(huà)得不好,但我還是堅(jiān)持把它畫(huà)完。如果不畫(huà)完,就...
    煙雨程程閱讀 486評(píng)論 5 6
  • 中華文化的集大成者,儒家學(xué)派創(chuàng)始人,我們偉大的圣人孔子曾說(shuō):"古之學(xué)者為己,今之學(xué)者為人。"想必大家可...
    似瑾年華閱讀 941評(píng)論 0 0
  • 那一年,心臟不怎么好,不確定自己能活多久(面對(duì)死亡,還是比較貪戀茍活于世滴),也無(wú)法想像年幼內(nèi)向的兒子,如果,...
    閣的畫(huà)本閱讀 7,049評(píng)論 225 540
  • 孤立和烏鴉的故事,是在小學(xué)都學(xué)過(guò)的,原來(lái)是出自這里。 小時(shí)候讀這個(gè)故事,覺(jué)得狐貍狡猾,烏鴉很傻。 ...
    懶猴1980閱讀 779評(píng)論 0 0

友情鏈接更多精彩內(nèi)容