蛋疼的cell 重用問題

以前也整過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;

完美解決,如果你有好的解決方案,也可以給我說一下,歡迎交流。





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章