2014-10-07 5 views
3

Я использую Xcode 6.0.1, iOS8 и Swift. Я должен воспроизвести в своем UITableView такое же поведение Автоблокировка в Настройки-> Общие. В Objective-C, в прошлом, я написалUITableView-Swift: Checkmark в UITableViewCell

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

Это отлично работает! Теперь в Swift, я писал:

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

И это не работает. Флажок появляется только иногда, и он исчезает при прокрутке. Я потратил два часа, чтобы понять, почему, но безуспешно.

+5

А где lastSelectedIndexPath должен быть объявлен? – Josh

ответ

11

Основная проблема заключается в том, что вы вызываете tableView(_:cellForRowAtIndexPath:) вместо tableView.cellForRowAtIndexPath(_:) и, таким образом, создаете новую ячейку вместо получения отображаемой на данный момент.

Вот некоторые очистки:

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 
    } 
} 
+0

Я использовал необязательное связывание, потому что self.lastSelectedIndexPath может быть nil – Giorgio

+0

Да, поэтому есть '?' В 'lastSelectedIndexPath? .row == row', который должен позаботиться об этом :) – fluidsonic

+0

Итак, два фрагмента кода эквивалентны? Я попытался использовать фрагмент кода, но результат тот же. – Giorgio

Смежные вопросы