UITableView-Swift: marca de verificación en UITableViewCell

Estoy usando Xcode 6.0.1, iOS8 y Swift. Tengo que reproducir en mi UITableView el mismo comportamiento de la opción de locking automático en Configuración-> General . En Objective-C, en el pasado, escribí

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CheckMarkCellIdentifier = @"CheckMarkCellIdentifier"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: CheckMarkCellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CheckMarkCellIdentifier] autorelease]; } cell.textLabel.text = ... cell.detailTextLabel.text = ...; cell.accessoryType = [indexPath isEqual: self.lastSelectedIndexPath] ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone; return cell; - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { int newRow = indexPath.row; int oldRow = self.lastSelectedIndexPath.row; if (newRow != oldRow) { UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath]; newCell.accessoryType = UITableViewCellAccessoryCheckmark; UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:self.lastSelectedIndexPath]; oldCell.accessoryType = UITableViewCellAccessoryNone; self.lastSelectedIndexPath = indexPath; } [tableView deselectRowAtIndexPath:indexPath animated:YES]; } 

Esto funciona muy bien! Ahora, en Swift, escribí:

 override func viewDidLoad() { super.viewDidLoad() ... self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "categoryCell") } func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { var cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier("categoryCell", forIndexPath: indexPath) as UITableViewCell cell.textLabel?.text = categories[indexPath.row] let row = indexPath.row; if let lastIndexPath = self.lastSelectedIndexPath { cell.accessoryType = (lastIndexPath.row == row) ? UITableViewCellAccessoryType.Checkmark : UITableViewCellAccessoryType.None; } return cell } func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { self.tableView.deselectRowAtIndexPath(indexPath, animated: true) let newRow = indexPath.row; var oldRow: Int? if let lastIndexPath = self.lastSelectedIndexPath { oldRow = lastIndexPath.row; let oldCell = self.tableView(tableView, cellForRowAtIndexPath: lastIndexPath) oldCell.accessoryType = UITableViewCellAccessoryType.None; } if (newRow != oldRow) { let newCell = self.tableView(tableView, cellForRowAtIndexPath: indexPath) newCell.accessoryType = UITableViewCellAccessoryType.Checkmark; self.lastSelectedIndexPath = indexPath; } } 

Y esto no funciona. La marca de verificación aparece solo algunas veces y desaparece cuando me desploop. Pasé dos horas para descubrir por qué, pero sin éxito.

El problema principal es que llama a tableView(_:cellForRowAtIndexPath:) lugar de tableView.cellForRowAtIndexPath(_:) y así crea una nueva celda en lugar de get la que se muestra actualmente.

Aquí hay algo de limpieza:

 override func viewDidLoad() { super.viewDidLoad() // … tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "categoryCell") } func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("categoryCell", forIndexPath: indexPath) as UITableViewCell cell.accessoryType = (lastSelectedIndexPath?.row == indexPath.row) ? .Checkmark : .None cell.textLabel?.text = categories[indexPath.row] return cell } func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { tableView.deselectRowAtIndexPath(indexPath, animated: true) if indexPath.row != lastSelectedIndexPath?.row { if let lastSelectedIndexPath = lastSelectedIndexPath { let oldCell = tableView.cellForRowAtIndexPath(lastSelectedIndexPath) oldCell?.accessoryType = .None } let newCell = tableView.cellForRowAtIndexPath(indexPath) newCell?.accessoryType = .Checkmark lastSelectedIndexPath = indexPath } }