"UITableView" iOS開發中重量級的控件之一;在平常開發中咱們大多數會選擇自定Cell來知足本身開發中的需求, 可是有些時候Cell也是能夠不自定義的(好比某一個簡單的頁面,只須要展現一些簡單的信息);可是當頁面大於屏幕顯示的範圍的時候, 滑動UITableView的時候,Cell上的內容會出現混亂或者錯誤的現象,通過反覆的查找問題應該是出如今UITableViewCell的重用機制上;那麼下面咱們就來講一下解決這種問題的幾種辦法,以及最好的解決辦法:ide
(一)使用系統的Cell,簡單的Cell重用機制咱們會這樣去寫:測試
1 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 2 static NSString *cellIdentifier = @"cellID"; 3 4 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 5 6 if (!cell) { 7 cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier]; 8 } 9 10 // 說明: 要測試Cell內容是否錯亂, 要將每行Cell顯示的內容不一樣, 才能看出來 11 cell.textLabel.text = @"Cell顯示內容"; 12 cell.detailTextLabel.text = @"Cell輔助顯示內容"; 13 14 return cell; 15 }
這樣寫雖然達到了Cell的重用, 可是會出現咱們要討論的話題(滑動UITableView出現Cell內容混亂的狀況),那麼下面咱們就來講一下避免Cell內容出現混亂的寫法;spa
(二)使用系統的Cell,避免Cell內容出現混亂的寫法:code
(1)方法一:orm
①將得到Cell的方法:- (UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier; 換爲:- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath;blog
②解決了Cell內容混亂的現象,可是沒有可以達到Cell的重用機制的原理;由於cellForRowAtIndexPath(只從要更新的cell的那一行取出cell),不使用重用機制,於是問題就能夠獲得解決,可是會浪費一些空間(真機測試比其餘方法略顯卡頓);隊列
③示例代碼:開發
1 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 2 static NSString *cellIdentifier = @"cellID"; 3 4 // UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 5 // 將上面的方法換成(根據indexPath準確地取出一行, 而不是從cell重用隊列中取出, 方法以下:) 6 UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 7 8 if (!cell) { 9 cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier]; 10 } 11 12 // 說明: 要測試Cell內容是否錯亂, 要將每行Cell顯示的內容不一樣, 才能看出來 13 cell.textLabel.text = @"Cell顯示內容"; 14 cell.detailTextLabel.text = @"Cell輔助顯示內容"; 15 16 return cell; 17 }
(2)方法二:rem
①經過爲每一個cell指定不一樣的重用標識符(reuseIdentifier)來解決;string
②重用機制是根據相同的標識符來重用Cell的,標識符不一樣的Cell不能彼此重用;咱們將每一個Cell的標識符都設置爲不一樣,就能夠避免不一樣Cell重用的問題了;
③示例代碼:
1 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 2 // static NSString *cellIdentifier = @"cellID"; 3 // 將上面的方法換成(以indexPath來惟一肯定Cell, 方法以下:) 4 NSString *cellIdentifier = [NSString stringWithFormat:@"Cell%zd%zd", [indexPath section], [indexPath row]]; 5 6 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 7 8 if (!cell) { 9 cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier]; 10 } 11 12 // 說明: 要測試Cell內容是否錯亂, 要將每行Cell顯示的內容不一樣, 才能看出來 13 cell.textLabel.text = @"Cell顯示內容"; 14 cell.detailTextLabel.text = @"Cell輔助顯示內容"; 15 16 return cell; 17 }
(3)方法三:
①經過刪除重用的Cell的全部子視圖,從而獲得一個沒有特殊格式的Cell,供其餘Cell重用;
②示例代碼:
1 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 2 static NSString *cellIdentifier = @"cellID"; 3 4 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 5 6 if (!cell) { 7 cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier]; 8 } else { 9 // 刪除Cell的全部子視圖 10 while ([cell.contentView.subviews lastObject] != nil) { 11 [(UIView*)[cell.contentView.subviews lastObject] removeFromSuperview]; 12 } 13 } 14 15 // 說明: 要測試Cell內容是否錯亂, 要將每行Cell顯示的內容不一樣, 才能看出來 16 cell.textLabel.text = @"Cell顯示內容"; 17 cell.detailTextLabel.text = @"Cell輔助顯示內容"; 18 19 return cell; 20 }
(以上即是對相關知識的相關介紹和理解,還但願你們相互補充共同進步)