iOS開發(fā) 簡化TableView

TableView 是iOS app 中最常用的控件,許多代碼直接或者間接的關(guān)聯(lián)到table view任務(wù)中,包括提供數(shù)據(jù)趁耗、更新tableView、控制tableView行為等等疆虚。下面會提供保持tableView代碼整潔和結(jié)構(gòu)清晰的方法苛败。

UITableViewController vs. UIViewController

TableViewController的特性

table view controllers可以讀取table view的數(shù)據(jù)满葛、設(shè)置tabvleView的編輯模式、反應(yīng)鍵盤通知等等罢屈。同時Table view controller能夠通過使用UIRefreshControl來支持“下拉刷新”嘀韧。

Child View Controllers

tableViewController也可以作為child view controller添加到其他的viewController中,然后tableViewController會繼續(xù)管理tableView缠捌,而parentViewController能管理其他我們關(guān)心的東西锄贷。

-(void)addDetailTableView

{

    DetailViewController *detail = [DetailViewController new];

    [detail setup];

    detail.delegate = self;

    [self addChildViewController:detail];

    [detail setupView];

    [self.view addSubview:detail.view];

    [detail didMoveToParentViewController:self];

}

如果在使用以上代碼時,需要建立child View controller 和 parent view controller之間的聯(lián)系曼月。比如谊却,如果用戶選擇了一個tableView里的cell,parentViewController需要知道這件事以便能夠響應(yīng)點(diǎn)擊時間十嘿。所以最好的方法是table view controller定義一個協(xié)議因惭,同時parent view controller實(shí)現(xiàn)這個協(xié)議。

@protocol DetailViewControllerDelegate

-(void)didSelectCell;

@end

@interface ParentViewController () <DetailViewControllerDelegate>

@end

@implementation ParentViewController

//....

-(void)didSelectCell

{

//do something...

}

@end

雖然這樣會導(dǎo)致view controller之間的頻繁交流绩衷,但是這樣保證了代碼的低耦合和復(fù)用性蹦魔。

分散代碼

在處理tableView的時候,會有各種各樣不同的咳燕,跨越model層勿决、controller層、view層的任務(wù)招盲。所以很有必要把這些不同的代碼分散開低缩,防止viewController成為處理這些問題的“堆填區(qū)”。盡可能的獨(dú)立這些代碼曹货,能夠使代碼的可讀性更好咆繁,擁有更好的可維護(hù)性與測試性。

消除ModelObeject和Cell之間的隔閡

在很多情況下顶籽,我們需要提交我們想要在view層展示的數(shù)據(jù)玩般,同時我們也行維持view層和model層的分離,所以tableView中的dateSource常常做了超額的工作:

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

{

Cell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];

[cell setup];

NSString *text = self.title;

cell.label.text = text;

UIImage *photo = [UIImage imageWithName:text];

cell.photoView.image = photo;

}

這樣dataSorce會變得很雜亂礼饱,應(yīng)該將這些東西分到cell的category中坏为。

@implementation Cell (ConfigText)

-(void)configCellWithTitle:(NSString *)title

{

self.label.text = title;

UIImage *photo = [UIImage imageWithName:title];

cell.photoView.image = photo;

return cell;

}

這樣的話dataSource將會變得十分簡單。

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

{

Cell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];

[cell configCellWithTitle:self.title];

return cell;

}

復(fù)用cell

其實(shí)還可以更進(jìn)一步镊绪,讓同一個cell變得可以展示多種的modelObject匀伏。首先需要在cell中定義一個協(xié)議,想要在這個cell中展示的object必須遵守這個協(xié)議蝴韭。然后可以修改分類中config method來讓object來遵守這個協(xié)議够颠,這樣cell就能適應(yīng)不同的數(shù)據(jù)類型。

在cell中處理cell狀態(tài)

如果想要對tableView的行為進(jìn)行設(shè)置榄鉴,如選中操作后改變高光狀態(tài)等摧找,可以在tableViewController中使用委托方法:

-(void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath

{

Cell *cell = [tableView cellForRowAtIndexPath:indexPath];

cell.label.shadowColor = [UIColor greenColor];

}

-(void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath

{

Cell *cell = [tableView cellForRowAtIndexPath:indexPath];

cell.label.shadowColor = nil;

}

然而當(dāng)想要換出這些cell或者想要重新設(shè)計(jì)的時候核行,仍然需要適應(yīng)委托方法。cell里面的detail的實(shí)現(xiàn)和委托方法中對detail的實(shí)現(xiàn)交織在一起蹬耘,所以應(yīng)該將這些邏輯移到cell里面:

@implementation Cell

//...

-(void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated

{

[super setHighlighted:highlighted animated:animated];

if(highlighted)

{

    self.label.shadowColor = [UIColor greenColor];

}

else

{

    self.label.shadowColor = nil;

}

}

@end

一個委托需要知道一個view的不同狀態(tài)芝雪,但它不需要知道怎么去修改view或者有哪些屬性需要設(shè)置來使這個view轉(zhuǎn)變狀態(tài),所有的邏輯應(yīng)該又view來完成综苔,而在外部只是僅僅提供一個API惩系。這樣才是view層和controller層實(shí)現(xiàn)代碼之間的有效分離。

處理不同的cell類型

如果在一個tableView中有不同的cell類型如筛,dataSource將會變得膨脹而難以操作堡牡,在下面的代碼中,有兩個不同的cell類型杨刨,一個負(fù)責(zé)展示圖片和標(biāo)題晤柄,另一個負(fù)責(zé)展示星標(biāo)。為了分離處理不同的cell的代碼妖胀,dataSource方法只是僅僅執(zhí)行不同cell自己的設(shè)置方法芥颈。

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

{

BOOL isStarRank = self.keys[(NSUInteger)indexPath.row];

UITableViewCell *cell;

if(isStarRank)

{

    cell = [self setupStarCell];

}

else

{

    cell = [self setupDefaultCell];

}

}

-(StarCell *)setupStarCell

{

//do something...

}

-(UITableViewCell *)setupDefaultCell

{

//do something...

}

編輯TableView

TableView提供了方便的編輯功能,能夠刪除和移動cell赚抡。這些事件中爬坑,tableView的dataSource通過委托方法獲取通知,因此經(jīng)常在這些委托方法中出現(xiàn)對數(shù)據(jù)的修改涂臣,而修改數(shù)據(jù)很明顯是model層的任務(wù)盾计。model應(yīng)該提供刪除、排序等的接口赁遗,這樣就能夠通過dataSource的方法來調(diào)用署辉。從而controller扮演了view和model之間的協(xié)調(diào)者,而不需要知道m(xù)odel層的實(shí)現(xiàn)細(xì)節(jié)岩四。同時這樣model的邏輯會變得更容易測試哭尝,因?yàn)闆]有混雜viewController的任務(wù)。

總結(jié)

tableViewController以及其他controller應(yīng)該扮演model和view的協(xié)調(diào)者和中介者炫乓,而不應(yīng)該關(guān)心屬于view或者model層的任務(wù)。謹(jǐn)記這點(diǎn)献丑,讓委托和dataSource變得更小和只包含公式化的代碼末捣。

這不只是減少tableViewController的體積和復(fù)雜度,同時也把域邏輯和界面邏輯放到相關(guān)的類中创橄,把實(shí)現(xiàn)細(xì)節(jié)包裹在簡單的API接口中箩做,最終提高了代碼的可讀性和代碼的協(xié)調(diào)能力。

以下文章可以做一個學(xué)習(xí)參考:

GCD面試要點(diǎn)

block面試要點(diǎn)

Runtime面試要點(diǎn)

RunLoop面試要點(diǎn)

內(nèi)存管理面試要點(diǎn)

MVC妥畏、MVVM面試要點(diǎn)

網(wǎng)絡(luò)性能優(yōu)化面試要點(diǎn)

網(wǎng)絡(luò)編程面試要點(diǎn)

KVC&KVO面試要點(diǎn)

數(shù)據(jù)存儲面試要點(diǎn)

混編技術(shù)面試要點(diǎn)

設(shè)計(jì)模式面試要點(diǎn)

UI面試要點(diǎn)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末邦邦,一起剝皮案震驚了整個濱河市安吁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌燃辖,老刑警劉巖鬼店,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異黔龟,居然都是意外死亡妇智,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門氏身,熙熙樓的掌柜王于貴愁眉苦臉地迎上來巍棱,“玉大人,你說我怎么就攤上這事蛋欣『结悖” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵陷虎,是天一觀的道長到踏。 經(jīng)常有香客問我,道長泻红,這世上最難降的妖魔是什么夭禽? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮谊路,結(jié)果婚禮上讹躯,老公的妹妹穿的比我還像新娘。我一直安慰自己缠劝,他們只是感情好潮梯,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著惨恭,像睡著了一般秉馏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上脱羡,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天萝究,我揣著相機(jī)與錄音,去河邊找鬼锉罐。 笑死帆竹,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的脓规。 我是一名探鬼主播栽连,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了秒紧?” 一聲冷哼從身側(cè)響起绢陌,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎熔恢,沒想到半個月后脐湾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡绩聘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年沥割,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片凿菩。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡机杜,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出衅谷,到底是詐尸還是另有隱情椒拗,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布获黔,位于F島的核電站蚀苛,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏玷氏。R本人自食惡果不足惜堵未,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望盏触。 院中可真熱鬧渗蟹,春花似錦、人聲如沸赞辩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽辨嗽。三九已至世落,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間糟需,已是汗流浹背屉佳。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留洲押,地道東北人武花。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像诅诱,于是被迫代替她去往敵國和親髓堪。 傳聞我的和親對象是個殘疾皇子送朱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

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