1. 程式人生 > >iOS UITableView 滑動時順序混亂或多個cell內容相同

iOS UITableView 滑動時順序混亂或多個cell內容相同

view sin 也會 一個隊列 section 一個 排序 一行 bsp

在使用UITableView時,由於cell的重用機制,在獲取後臺數據並填充cell時,會發生cell重復出現,界面紊亂。但這僅僅在擁有多個section的情況下會出現,沒有滾動的時候,單個section的row顯示的都是正確的。

以下是示例代碼:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
//這個方法是UITableView 的 DataSource方法,作用是用來加載/重用cell的。
 
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    
static NSString *SimpleTableIdentifier = @"SimpleTableIdentifier"; // UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: SimpleTableIdentifier]; UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; if (cell == nil) { // ... your code cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier: SimpleTableIdentifier]; }
return cell; }

這裏面的變量其實每創建一次tableViewController都會出現

1. SimpleTableIdentifier:cell的標識, dequeueReusableCellWithIdentifier方法會用到。在alloc cell的時候會傳入SimpleTableIdentifier並賦給cell的reuseIdentifier屬性
。如果使用dequeueReusableCellWithIdentifier來獲取cell,就要確保每個indexPath.row所指向的cell的SimpleTableIdentifier唯一。

2. dequeueReusableCellWithIdentifier::這個方法會返回reuseIdentifier與當前SimpleTableIdentifier相同的cell,這也就是造成順序混亂的原因,如果沒有找到,返回nil

3. cellForRowAtIndexPath::這個方法會返回與當前indexPath相同的cell,所以就算是所有cell的SimpleTableIdentifier都相同,也會得到正確順序,如果沒有找到,返回nil

總結

如果在你的程序中,出現排序混亂或cell內容相同的情況,請核對使用的是dequeueReusableCellWithIdentifier方法還是cellForRowAtIndexPath方法。

由於cellForRowAtIndexPath方法不會出現這種情況,所以如果使用的是dequeueReusableCellWithIdentifier方法,請確保每個cell的reuseIdentifier唯一。

但是cell重用的機制也不能忽略,UITableViewCell有一個隊列用來專門存放那些生成過的,但是後來由於滾動tableView而隱藏起來的cell,

比如一個table有20個cell,但是屏幕只能顯示5個,(當然iPhone5可能會顯示6個),那麽就會有其他的cell沒有顯示出來,但是在滑動tableview的時候便會顯現。

而代碼中:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: SimpleTableIdentifier];

就是從隊列中根據標示符取出一個暫時不用的cell,只有cell為nil,也就是隊列中沒有舊的cell的時候,才會執行:

        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                      reuseIdentifier: SimpleTableIdentifier];

以此生成一個新的cell。

如果有舊的,就不用執行這個語句了,這樣節省資源,算作一種重用。

在tableView初始化的時候隊列中肯定沒有cell的,所以每個cell生成的時候都會執行一遍這個代碼:

        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                      reuseIdentifier: SimpleTableIdentifier];

當屏幕顯示滿了,向上滾動顯示下一行時,就會把第一行隱藏,放到那個隊列中,然後新增加的一行執行語句:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: SimpleTableIdentifier];
這時候結果就不是nil了,然後,就跳過語句2了,這樣就節約資源了。

iOS UITableView 滑動時順序混亂或多個cell內容相同