UITableView-Swift:UITableViewCell中的Checkmark

时间:2014-10-07 14:30:44

标签: ios uitableview swift ios8 checkmark

我正在使用Xcode 6.0.1,iOS8和Swift。 我必须在UITableView中重现设置 - >常规自动锁定选项的相同行为。在Objective-C中,我写过

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

这不起作用。复选标记有时仅出现,当我滚动时它会消失。我花了两个小时才弄明白为什么但没有成功。

1 个答案:

答案 0 :(得分: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
    }
}