參考:http://zhidao.baidu.com/link?url=_oMUTo5SxUY6SBaxYLsIpN3i2sZ6SKG35MVlPJd2cNmUf9TGQFkKXX9EXwSwti0nX08gR8j4je4WPXzKq96Ts29r3aZBcLDDVMJdWLGYzCy
例1:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = @"cell1";
UITableViewCell *cell =[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
UILabel *labelTest = [UILabel alloc]init];
[labelTest setFrame:CGRectMake(2, 2, 80, 40)];
[labelTest setBackgroundColor:[UIColor clearColor];
[labelTest setTag:1];
[cell contentView]addSubview:labelTest];
}
UILabel *label1 = (UILabel*)[cell viewWithTag:1];
[label1 setText:[self.tests objectAtIndex:indexPath.row];
return cell;
}
例2:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath{
static NSString *CellIdentifier = @"cell1";
UITableViewCell *cell =[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
UILabel *labelTest = [UILabel alloc]init];
[labelTest setFrame:CGRectMake(2, 2, 80, 40)];
[labelTest setBackgroundColor:[UIColor clearColor]; //之所以這里背景設為透明,就是為了后面讓大家看到cell上疊加的label。
[labelTest setTag:1];
[cell contentView]addSubview:labelTest];
[labelTest setText:[self.tests objectAtIndex:indexPath.row];
return cell;
}
當你上下來回滑動tableview的時候就會看到區別,第一種程序界面不會出現異常,但是第二種就不是了,會出現字體疊加現象,其實更確切的是多個label的疊加。為什么呢,因為在tableview刷新的時候,如果那個位置已經有現成的cell,它就不會再重新請求資源生成新的cell了,而是復用原來的cell。所以對於對於第一種,代碼的思路是第一次在cell不存在的時候生成cell,定義cell樣式,以后不管是刷新還是重新請求還好,它都只是復用已生成的cell。而第二種思路是,在cell不存在的時候,請求生成cell,然后給cell上添加label,刷新的時候,會復用已有的cell,但是會重復添加label,故造成重疊的現象。
http://m.blog.csdn.net/blog/heyehao2008/27806945
在使用TableView的時候,下面一段代碼是必須的,也是最標准的: - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CMainCell = @"CMainCell"; // 0 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CMainCell]; // 1 if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier: CMainCell] autorelease];// 2 } // Config your cell cell.textlabel.text = @"XXX"; // 3 return cell; } 可以這樣理解,cell有一個地方(假設稱為隊列),專門存放那些生成過的,但是后來由於滾動tableView而隱藏起來的cell,而代碼中語句1就是從隊列中根據標示符取出一個暫時不用的cell,只有cell為nil,也就是隊列中沒有舊的cell的時候,才會執行語句2,生成一個新的cell。如果有舊的,就不用執行語句2了,這樣節省資源,算作一種重用吧。在tableView初始化的時候隊列中肯定沒有cell的,所以每個cell生成的時候都會執行一遍2,當屏幕顯示滿了,向上滾動顯示下一行時,就會把第一行隱藏,放到那個隊列中,然后新增加的一行執行語句1的時候,結果就不是nil了,然后,就跳過語句2了,這樣就節約資源了。 當然,上面這樣對於使用系統提供的cell格式是沒有什么問題,但是如果自己在cell上添加一些控件時,比如一個label,有時就會出現問題。尤其是各個cell的label的文字不相同時。首先這個添加的過程一定要在語句2之后,這樣才是一次添加,如果放在語句3之后,那么由於cell的重用可能舊的上面已經有label了,你再添加一個,造成多次添加。其次label的文本值必須保證每次都要重新設置,也就是在語句3之后設置,這樣才能保證每次必須執行。如果放在語句2后面,那么當使用舊的cell時,仍會保留舊的label文字,這是不對的。所以是在2后添加,在3后設置,可以在2添加的時候設一個tag值,這樣可以在3處通過tag值獲取控件設置。 關於語句0,如果每個cell的結構完全相同,那沒問題,就用這一個標識符,但是如果各個cell結構不完全相同,有的有textfield,有的有button,有的有switch,那就不能互相重用了,只能每行用不同的標識符了,可以方便的利用(@"CMainCell%d", indexPath.row),保證不會重復,多組的再加上組號。那這還有必要用語句2嗎?還是需要的,因為當自己滾動隱藏,下次再顯示出來的時候,還是可以重用的。標識符完全可以每次用一個新的,但為了最大限度的重用性,節省資源,才想了這么多辦法。 總之,注意添加控件的位置,注意設置控件的位置,注意cell標識符。
當我們的uitableview為透明或者判斷cell是否為空時,會發現uitableveiwcell會出現重疊,下面為自己的解決辦法,提供給各位參考 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ UITableViewCell *cell=nil; static NSString *reuse=@"cell"; if (cell==nil) { cell=[[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuse] autorelease]; }else{ while ([cell.contentView.subviews lastObject] != nil) { [(UIView*)[cell.contentView.subviews lastObject] removeFromSuperview]; //刪除並進行重新分配 } } cell.textLabel.text=@"cell"; return cell; }
另一種寫法
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellIdetify = @"cell"; UITableViewCell *tvCell = [tableView dequeueReusableCellWithIdentifier:cellIdetify]; if(tvCell == nil) { NSLog(@"cell = nil"); tvCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdetify] autorelease]; }else{ NSLog(@"cell !=nil "); NSArray *views = [tvCell subviews]; for (UIView *obj in views) { if (obj.tag==1000 || obj.tag==2000) { //只刪除指定的畫面,不要全部刪除,否則tableview的分割線也會被刪除 NSLog(@"cell 要刪除的子畫面是:%@",[obj class]); [obj removeFromSuperview]; } }
轉載:http://www.cnblogs.com/ygm900/archive/2013/06/13/3134436.html
如何實現 cell的重用?
主要是通過 UITableView的 “dequeueReusableCellWithIdentifier” 函數來實現,從字面上理解是“出列的可重用的cell”,其實簡單說就是一個cell池,里面放的就是你之前創建過的cell。
注意點:
1,重取出來的cell是有可能已經捆綁過數據或者加過子視圖的,如果有必要,要清除需要用與顯示的數據和remove掉add過的子視圖(使用 tag—viewWithTag 獲取相關視圖對象)。
2,原理就是為了避免頻繁的 alloc和delloc cell對象。
3,設計的關鍵是實現cell和數據的完全分離。
介紹:一個屏幕顯示的cell數量是有限的,當屏幕滾動時候,就會調用方法獲取新的cell,而老的cell會在屏幕外面就不顯示了。reuse機制就是這樣,當cell需要顯示的時候,從queue里面找,找到了,設置一下內容,顯示出來。滾動界面當有cell被移出屏幕時,把這個cell丟到queue里面,顯示新的cell時,如果有“相同類型”(identifier)的cell,就從隊列拿一個出來,設置數據,顯示出來,至於queue里面會有多少cell,這個會自動控制。