【问题标题】:How can I keep a cell selected while scrolling the tableView?滚动 tableView 时如何保持选中单元格?
【发布时间】:2016-03-17 12:54:12
【问题描述】:

我希望一个单元格在被触​​摸时保持选中状态,如果再次被触摸则取消选中。这是我的代码不起作用:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    let selectedCell = tableView.cellForRowAtIndexPath(indexPath)
    if let value = selectedCell?.selected.boolValue {
        if !value {
            print("cell was selected and will remain selected") 
            selectedCell?.selected = true
        } else {
            print("cell is deselected")
            selectedCell?.selected = false
        }
    }
}

我该如何实现?

【问题讨论】:

  • 您需要将单元格状态保存在一个数组中,然后在 cellForRowAtIndexPath 中使用它来区分应该选择哪个单元格,哪些不应该选择。
  • 以及如何取消选择之后的选择。现在我只想让它适用于一个单元格。但是数组的想法将是必要的,因为我正在实施一个完整的菜单来使用此功能
  • 你需要实现didSelectRowAtIndexPath和didDeselectRowAtIndexPath,
  • 在此之前创建一个数组,该数组将具有与单元格相同数量的对象。在数组中为所有对象添加 @"NO" 字符串。然后是在didSelectRowAtIndexPath 中简单地做arrayCellState replaceObjectAtIndexPath: indexPath.row withObject:@"YES" 反之亦然在didDeselectRowAtIndexPath 中。然后在 cellForRowAtIndexPath 检查选定的单元格 if([[arrayCellState objectAtIndex:indexPath.row] isEqualToString: @"YES"]) ,如果是 cell.setSelected = YES;反之亦然。

标签: ios swift uitableview


【解决方案1】:

记住规则:

  • 在模型中存储单元格数据
  • UITableViewController 仅用于可视化

在您的代码中,通过indexPath.row 存储选定的值,例如在数组中

【讨论】:

  • 是的,我知道,但我只是想直观地表明该选项确实保存在数据模型中。由于某些设计限制,我不想使用附件类型来实现它
  • @irkinosor 你不需要使用附件类型。如果它被选中,你可以重绘单元格的背景。
【解决方案2】:

如果您一次只有一个选定的行,那么即使没有数据模型(您应该拥有),您也可以拥有 ViewController selectedRowIndex 的属性,每次选择一行时都会更新,并刷新 tableView - 作为cellForRowAtIndexPath 的一部分,您可以检查 indexPath.row == selectedRowIndex 并进行所需的任何视觉更改

定义一个属性来跟踪当前选中的行

var selectedRowIndex = -1

然后在用户选择一行时更新该属性

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
    // build up an array of rows to be refreshed
    // the previously selected row (if any)
    // and the current one
    var indexPaths : [NSIndexPath] = []

    // if a row was previous selected, clear the display
    if selectedRowIndex != -1
    {
        indexPaths.append(NSIndexPath(forRow: selectedRowIndex, inSection: 0))
    }

    selectedRowIndex = indexPath.row
    indexPaths.append(NSIndexPath(forRow: selectedRowIndex, inSection: 0))

    // now refresh just those rows
    self.tableView.reloadRowsAtIndexPaths(indexPaths, withRowAnimation: UITableViewRowAnimation.None)

}

然后在重新绘制行时对其进行处理

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
    let cell = tableView.dequeueReusableCellWithIdentifier("MyCell", forIndexPath: indexPath) as! MyCell

    if indexPath.row == selectedRowIndex
    {
        cell.backgroundColor = UIColor.greenColor()
    }
    else
    {
        cell.backgroundColor = UIColor.whiteColor()
    }
      // everything else
    return cell
}

【讨论】:

  • cellForRowAtIndexPath 只能调用一次,对吗?当表第一次加载时。但我希望这种突出显示/取消突出显示以交互方式发生,就像它适用于附件类型检查标记一样
  • willDisplayCell 函数中而不是cellForRowAtIndexPath 中进行复选标记调整。
  • 谢谢 Rusell,但恐怕你没有正确理解我的问题。并记住 cellForRowAtindexPath 只能在开始时被调用。当用户点击单元格时,我希望单元格立即突出显示/不突出显示
  • 试一试 - tableView.reloadRowsAtIndexPaths 将强制重绘您刚刚选择的行和之前选择的行,cellForRowAtindexPath 将被重新调用。
  • 对不起,我很困惑,我的意思是改变颜色,而不是复选标记。你试过使用willDisplayCell 吗?
【解决方案3】:

您可以将cellForRowAtIndex中每个单元格的默认标签值设置为cell.tag = 0

didSelectRowAtIndexPath 函数中,你可以做这样的事情

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

   let selectedCell = tableView.cellForRowAtIndexPath(indexPath)
   if selectedCell.tag == 0 {
       print("cell was selected")
       selectedCell.tag = 1
   }
   else {
       print("cell was deselected")
       selectedCell.tag = 0
   }

}

【讨论】:

  • 这不起作用,因为从 cellForRowAtIndexPath 加载表格时没有选择任何单元格。
  • 谢谢伙计,但没有。感谢您的努力!
  • 你有什么问题?
  • 我添加了我的解决方案。检查它如何
  • 酷!愿原力与你同在。
【解决方案4】:

好吧,这就是我设法做到这一点的方法,声明一个 var selectedIndexPath: NSIndexPath? 然后在 didSelectRowAtindexPath 中执行以下操作:

            if selectedIndexPath == indexPath {
                tableView.deselectRowAtIndexPath(indexPath, animated: true)
                selectedIndexPath = nil
            }else{
                tableView.selectRowAtIndexPath(indexPath, animated: true, scrollPosition: .None)
                selectedIndexPath = indexPath
            }

【讨论】:

  • 您没有使用didDeselectRowAtIndexPath: 方法有什么原因吗?
【解决方案5】:

我的理解是默认情况下会处理单元格的选择和取消选择-您不必自己弄乱单元格的选定值!

您可能需要根据所选状态更新tableView:cellForRowAtIndexPath: 方法中单元格的某些元素。

如果这不是开箱即用的和/或您想自定义此行为,您也应该查看tableView:didDeselectRowAtIndexPath: 方法。这两种方法的结合应该可以让您完全控制选定的状态。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多