以前也整過tableView ,但從來沒被cell 的重用問題搞暈過頭,可能是因爲寫的table太簡單了吧。這次是重用各種出問題,以至於都沒信心寫tableView 了。
首先得弄清楚cell的重用是怎麼一回事,TableView的重用機制,爲了做到顯示和數據分離,IOS tableView的實現並且不是爲每個數據項創建一個tableCell。而是隻創建屏幕可顯示最大個數的cell,然後重複使用這些cell,對cell做單獨的顯示配置,來達到既不影響顯示效果,又能充分節約內容的目的。TableView顯示之初,reusableTableCells爲空,那麼tableView dequeueReusableCellWithIdentifier:CellIdentifier返回nil。開始的cell都是通過[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier]來創建,而且cellForRowAtIndexPath只是調用最大顯示cell數的次數。
比如:有100條數據,iPhone一屏最多顯示10個cell。程序最開始顯示TableView的情況是:
1. 用[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]創建10次cell,並給cell指定同樣的重用標識(當然,可以爲不同顯示類型的cell指定不同的標識)。並且10個cell全部都加入到visiableCells數組,reusableTableCells爲空。
2. 向下拖動tableView,當cell1完全移出屏幕,並且cell11(它也是alloc出來的,原因同上)完全顯示出來的時候。cell11加入到visiableCells,cell1移出visiableCells,cell1加入到reusableTableCells。
3. 接着向下拖動tableView,因爲reusableTableCells中已經有值,所以,當需要顯示新的cell,cellForRowAtIndexPath再次被調用的時候,tableView dequeueReusableCellWithIdentifier:CellIdentifier,返回cell1。cell1加入到visiableCells,cell1移出reusableTableCells;cell2移出visiableCells,cell2加入到reusableTableCells。之後再需要顯示的Cell就可以正常重用了。
所以整個過程並不難理解,但需要注意正是因爲這樣的原因:配置Cell的時候一定要注意,對取出的重用的cell做重新賦值,不要遺留老數據。
明白了cell 的重用機制,所以我們在遇到這個問題的時候就有很好的解決辦法了,我的解決辦法是不同的cell 利用不同的標示符,上代碼舉例子。
圖片上的問題明顯都是cell的重用用錯了。下面看我的代碼如何解決了這一問題。
int section = indexPath.section;
int row = indexPath.row;
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (section == 0) {
static NSString *cellfirstID = @"cellfirstID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellfirstID];
if (cell == nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellfirstID];
}
if (row == 0)
{
smallBtn = [UIButton buttonWithTitle:@"小" titleColor:[UIColor lightGrayColor] backgroundColor:[UIColor whiteColor] target:self action:@selector(smallAction:)];
[smallBtn setBackgroundImage:[UIImage imageNamed:@"bg1_size_img"] forState:UIControlStateNormal];
[smallBtn setBackgroundImage:[UIImage imageNamed:@"bg2_size_img"] forState:UIControlStateHighlighted];
[smallBtn setBackgroundImage:[UIImage imageNamed:@"bg2_size_img"] forState:UIControlStateSelected];
[smallBtn setFrame:CGRectMake(190, 15, 40, 28)];
[cell addSubview:smallBtn];
middleBtn = [UIButton buttonWithTitle:@"中" titleColor:[UIColor lightGrayColor] backgroundColor:[UIColor whiteColor] target:self action:@selector(middleAction:)];
[middleBtn setBackgroundImage:[UIImage imageNamed:@"bg1_size_img"] forState:UIControlStateNormal];
[middleBtn setFrame:CGRectMake(230, 15, 40, 28)];
[middleBtn setBackgroundImage:[UIImage imageNamed:@"bg1_size_img"] forState:UIControlStateNormal];
[middleBtn setBackgroundImage:[UIImage imageNamed:@"bg2_size_img"] forState:UIControlStateHighlighted];
[middleBtn setBackgroundImage:[UIImage imageNamed:@"bg2_size_img"] forState:UIControlStateSelected];
[cell addSubview:middleBtn];
bigBtn = [UIButton buttonWithTitle:@"大" titleColor:[UIColor lightGrayColor] backgroundColor:[UIColor whiteColor] target:self action:@selector(bigAction:)];
[bigBtn setFrame:CGRectMake(270, 15, 40, 28)];
[bigBtn setBackgroundImage:[UIImage imageNamed:@"bg1_size_img"] forState:UIControlStateNormal];
[bigBtn setBackgroundImage:[UIImage imageNamed:@"bg2_size_img"] forState:UIControlStateHighlighted];
[bigBtn setBackgroundImage:[UIImage imageNamed:@"bg2_size_img"] forState:UIControlStateSelected];
[cell addSubview:bigBtn];
cell.textLabel.text = @"字體大小";
}
else if (section == 1)
{
static NSString *cellSecondID = @"cellSecondID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellSecondID];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellSecondID];
}
if (row == 0) {
cell.textLabel.text = @"清楚緩存";
}
if (row == 1) {
cell.textLabel.text = @"推薦給朋友";
}
if (row == 2) {
cell.textLabel.text = @"幫助";
}
if (row == 3) {
cell.textLabel.text = @"版本更新";
}
if (row == 4) {
cell.textLabel.text =@"關於我們";
}
return cell;
}
return cell;
完美解決,如果你有好的解決方案,也可以給我說一下,歡迎交流。