1.1 復用機制
在我們使用UITableView 和 UICollectionView時,通常會復用cell,當需要展示的數(shù)據(jù)條較多時,只創(chuàng)建較少數(shù)量的cell 對象,一般是屏幕可顯示測Cell 數(shù)+ 1, 通過復用的方式來展示數(shù)據(jù). 這種機制不會為每一條數(shù)據(jù)都創(chuàng)建一個Cell,所以可以節(jié)省內(nèi)存,提升程序的效率和交互流暢性. 另外,在iOS 6以后,section中的Header 和Footer也能復用
復用會用到的API:
復用機制不正確的使用會給我們的程序帶來很多問題
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString * CellIdentifier = @"UITableViewCell"; UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; // 偶數(shù)行 Cell 的 textLabel 的文字顏色為紅色董虱。 if (indexPath.row % 2 == 0) { [cell.textLabel setTextColor:[UIColor redColor]]; } } cell.textLabel.text = @"Title"; // 偶數(shù)行 Cell 的 detailTextLabel 顯示 Detail 文字。 if (indexPath.row % 2 == 0) { cell.detailTextLabel.text = @"Detail"; } return cell; }
我們本來只是希望只有偶數(shù)行的textLabel的文字顏色為紅色,并 且顯示Detail文字,但是當你滑動TableView的時候發(fā)現(xiàn)不對了,有些奇數(shù)行的textLabel的文字顏色為紅色,而且還顯示了Detail文字. 這種情況的出現(xiàn)就是因為/復用/,如果剛好某一個cell 沒有顯式的設置它的屬性,那么它這些屬性就直接復用別的cell. 還有一個問題就是,對偶數(shù)行的cell 的textLabel的文字顏色設置放在了初始化一個cell的if代碼塊中,這樣在復用cell的時候,因為cell != nil, 邏輯走不到這里,所以這樣也會出現(xiàn)復用問題,所以我們將cell的顏色屬性改變設置在cell != nil 的時候,放在cell復用的地方
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString * CellIdentifier = @"UITableViewCell"; UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; } cell.textLabel.text = @"Title"; if (indexPath.row % 2 == 0) { [cell.textLabel setTextColor:[UIColor redColor]]; cell.detailTextLabel.text = @"Detail"; } else { [cell.textLabel setTextColor:[UIColor blackColor]]; cell.detailTextLabel.text = nil; } return cell; }
2. 1控件重疊
在UITableViewCell的使用中,使用純代碼方式添加控件,當復用cell的時候,可能出現(xiàn)控件重疊現(xiàn)象.我們可能需要對cell中添加的控件進行清空,cell的復用不變,只是在新的cell加載前,都會對上一個cell的contentView貼的控件進行清空,代碼如下
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString *CellIdentifer = @"DiscoverHomeInnerTableViewCell"; DiscoverHomeInnerTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifer forIndexPath:indexPath]; //TODO 解決cell復用重疊問題 for (UIView *subview in [cell.contentView subviews]) { [subview removeFromSuperview]; } UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; //button相關設置 [cell.contentView addSubview:button]; UILabel *lab = [[UILabel alloc] init]; //lab相關設置 [cell.contentView addSubview:lab]; }
從上面分析得知,在復用cell的時候需要注意的問題點:
- 若要設置不同行數(shù)或者在某些條件下,不同的cell屬性(包括樣式,內(nèi)容)時,要注意不能在cell 初始化內(nèi)部中設定,要放在初始化的外部,同時用if 和else 顯式的覆蓋所有的可能性,對所有的可能性進行判斷和設定屬性;
本文的第一部分 ,有關"復用機制"的討論,引用并參考了冰晨-簡書