UITableView-Swift: une Coche dans UITableViewCell

Je suis en utilisant Xcode 6.0.1, iOS8 et Swift.
J'ai de reproduire dans mon UITableView le même comportement de la de Verrouillage Automatique de option dans Paramètres->Général. En Objective-C, dans le passé, j'ai écrit

- (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];
}

Cela fonctionne très bien!
Maintenant, dans Swift, j'ai écrit:

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;
    }
}

Et cela ne fonctionne pas. La coche n'apparaît que parfois, et il disparaît quand je scroll. J'ai passé deux heures à comprendre pourquoi, mais sans succès.

Et où est lastSelectedIndexPath censé être déclaré?

OriginalL'auteur Giorgio | 2014-10-07