ios - 遍历 TableViewCells 会跳过一些

标签 ios swift cocoa-touch

我有一个表格 View ,每个单元格中都有一个复选框。我还有一个“全选”按钮。

我的问题是,当我单击全选时,我想将所有复选框更新为选中状态。因此,从 100 个单元格的列表中,所有单元格都会被检查,但每第 13 个单元格不会被检查。为了更清楚,在我的模拟器屏幕上有 12 个可见的单元格,所有单元格都经过检查。当我开始滚动时,出现的第一个单元格未选中,然后是 12 个选中的单元格:S 当我稍微滚动并再次单击“全选”时,跳过的也会被选中..

有人知道我错过了什么吗?

这是单元格代码:

class ListTableViewCell: UITableViewCell {

@IBOutlet weak var checkbox: UIButton!
var buttonState = false{
    didSet{
        if buttonState{
            checkbox.setImage(#imageLiteral(resourceName: "checked"), for: .normal)
        }else{
            checkbox.setImage(#imageLiteral(resourceName: "unchecked"), for: .normal)
        }
    }
}

@IBAction func checkboxAction(_ sender: UIButton) {

    if buttonState {
        buttonState = false                                  
    }else{
        buttonState = true
    }
}

func simulateCheck(){
    buttonState = true
 }

下面是我的 Controller 的一些片段:

 private var articleValues: [ArticleValue] = []{
    didSet{
        tableView.reloadData()

    }
}
func selectAll(){

    for i in 0..<articleValues.count{            
        let cell = tableView.cellForRow(at: IndexPath(item: i, section: 0)) as? ListTableViewCell
        cell?.simulateCheck()
        tableView.reloadData()          
    }   
}


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "articleValueItem", for: indexPath)

    // Cell Configuration
    let articleValue = articleValues[indexPath.row]
    if let articleValueCell = cell as? ListTableViewCell{
        articleValueCell.articleValue = articleValue
    }
    return cell
}

最佳答案

您的 UITableView 由数据源支持。这意味着您不应像此处那样直接更改单元格:

cell?.simulateCheck()
tableView.reloadData()          

相反,您应该保留所有已检查位置的列表,也许是另一个数组,每个对应的 articleValue 都有 bool 值(这不是最好的设计)。

var checkedValues = bool 值

在你的 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 方法,然后您将设置单元格的状态:

articleValueCell.buttonState = checkedValues[indexPath.row]

在您的 selectAll 方法中,用 true 值填充此数组,然后调用 tableView.reloadData()

private var checkedValues = [Bool]()
private var articleValues: [ArticleValue] = []{
    didSet{
        checkedValues = Array(repeating: false, count: articleValues.count)
        tableView.reloadData()
    }
}

func selectAll(){
    checkedValues = Array(repeating: true, count: articleValues.count)
    tableView.reloadData()
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "articleValueItem", for: indexPath)

    // Cell Configuration
    let articleValue = articleValues[indexPath.row]
    if let articleValueCell = cell as? ListTableViewCell{
        articleValueCell.articleValue = articleValue
        articleValueCell.buttonState = checkedValues[indexPath.row]
    }
    return cell
}

另一个错误是您永远不应该迭代表格中的所有单元格,因为它们会被重复使用,没有必要遍历您的数据源并为每个单元格获取一个单元格。只有遍历 tableView.visibleCells 才有意义。但就像你的情况一样,大多数时候你也不需要,你应该相应地更新你的数据源并重新加载表格或只是修改后的单元格。

关于ios - 遍历 TableViewCells 会跳过一些,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45444297/

相关文章:

swift - 调试 nil 选项

json - 如何在get请求中发送json body

iphone - 如何以编程方式使铃声静音或更改 iOS5 上的铃声

ios - 打开 map 应用程序 iOS 6 后以编程方式返回 iOS 应用程序

ios - 将 AVPlayerItem 保存到文档目录

swift - UIScrollview 中的 UIImage 具有长宽比填充

ios - Adobe Air 3.6 出现阻止备份的问题

iphone - Xcode 的构建和存档不起作用

java - 处理来自应用程序的非 UI 部分的导航?

ios - 如何在缩放 imageView 时防止缩放 parantView