2014-07-15 46 views
3

我有一個非常簡單的UITableViewController子類,用於向用戶顯示單元格中字母表中的字符。當用戶按下一個單元格時,將其附件類型設置爲複選標記。UITableViewController更改一個可重用的單元格會影響其他單元格

#import "MTGTableViewController.h" 

@interface MTGTableViewController() 

@property (nonatomic, strong) NSArray *data; 

@end 

@implementation MTGTableViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    _data = @[@"A", @"B", @"C", @"D", @"E", @"F", @"G", @"H", @"I", @"J", @"K", @"L", @"M", @"N", @"O", @"P", @"Q", @"R", @"S", @"T", @"U", @"V", @"W", @"X", @"Y", @"Z"]; 
} 

#pragma mark - Table view data source 

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{ 
    // Return the number of sections. 
    return 1; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    return _data.count; 
} 


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"reuseIdentifier" forIndexPath:indexPath]; 

    // Configure the cell... 
    cell.textLabel.text = _data[indexPath.row]; 

    return cell; 
} 

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 
    cell.accessoryType = UITableViewCellAccessoryCheckmark; 
} 

@end 

表視圖工作正常。我在我的原型單元格的故事板中設置了我的reuseIdentifier屬性,並且在我開始選擇單元格之前它看起來都很好。

問題:當我選擇任何單元格時,比如說「A」單元格,當我向下滾動它們時,其他尚未可見的單元格也會給出複選標記。更糟糕的是,當我上下滾動時,有時單元格「A」上的複選標記將被刪除並提供給單元格「B」。

+1

@downvoter爲什麼呢? – michaelsnowden

回答

3

前一段時間我也遇到了這個問題,您需要添加另一個數組來跟蹤哪個單元格被標記。只需製作一組標記爲NSIndexPath的數組。 有點像:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 
    if ([arrayOfMarked containsObject:indexPath]) { 
     cell.accessoryType = UITableViewCellAccessoryNone; 
    } else { 
     cell.accessoryType = UITableViewCellAccessoryCheckmark; 
    } 
} 
+0

該死的,這很爛。但這是我最終做的。 – michaelsnowden

+0

@michaelsnowden這不是最好的選擇。我問了一個類似的問題,結果你需要爲你的單元提供一個「默認」狀態,因爲它們正在被重用。 (@尼古拉斯哈特下面,實際上是暗示) 這裏是我的問題的鏈接; http://stackoverflow.com/questions/39198461/uitableviewcell-reusability-issue-modifying-one-cell-is-affecting-others – Priest

5

這是因爲表格視圖重用單元格的方式。在您調用dequeueReusableCellWithIdentifier之後,您需要確保清除附件項目。例如:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"reuseIdentifier" forIndexPath:indexPath]; 

    // Configure the cell... 
    cell.textLabel.text = _data[indexPath.row]; 
    cell.accessoryType = UITableViewCellAccessoryNone; 

    return cell; 
} 

雖然 - 您在進行此更改後會遇到不同的問題。由於這個代碼,單元格會「忘記」它被選中。因此,您需要實際更改accessoryType設置爲檢查的行,並查看單元格是否已選中。

0

didselectRowAtIndex路徑上,索引路徑追加到indexpath陣列

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 


    if selectedIndexPaths.contains(indexPath) { 

     let indexOfIndexPath = selectedIndexPaths.indexOf(indexPath)! 
     selectedIndexPaths.removeAtIndex(indexOfIndexPath) 
    } else { 
     selectedIndexPaths += [indexPath] 
    } 

    tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic) 

} 

,然後在的cellForRowAtIndexPath使用selectedIndexpaths陣列如果所選擇的小區來檢查或不

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 

    let mycell = tableView.dequeueReusableCellWithIdentifier("yourCell", forIndexPath: indexPath) as! YourCustomCell 
. 
. 
. 
    if selectedIndexPaths.contains(indexPath){ 
// do what you want to do if the cell is selected 


    } else { 

// do what you want to do if the cell is not selected 
    } 
0

的SWIFT 3:

我發現的一個簡化版本是在「cellForRowAt」函數中使用swifts 「.indexPathsForSelectedRows」

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomTableViewCell 

    //To keep from reusing checkmark in reusableCell 
    if let selectedIndexPaths = tableView.indexPathsForSelectedRows { 
     if selectedIndexPaths.contains(indexPath) { 
      cell.accessoryType = .checkmark 
     } else { 
      cell.accessoryType = .none 
     } 
    } 

    cell.contactsOutlet.text = namesOrganized[indexPath.section].names[indexPath.row] 
    return cell 
} 

然後在didSelect和didDeselect:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 

    let cell = tableView.cellForRow(at: indexPath) 
    cell?.accessoryType = UITableViewCellAccessoryType.checkmark 
} 

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { 

    let cell = tableView.cellForRow(at: indexPath) 
    cell?.accessoryType = UITableViewCellAccessoryType.none 
} 
相關問題