filterTableViewController.reloadRows 仅在第一次调用时重新加载行 [英] filterTableViewController.reloadRows reloading rows only on first call

查看:39
本文介绍了filterTableViewController.reloadRows 仅在第一次调用时重新加载行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个表格,每行有 3 行,每行都带有复选按钮.我正在做的是当我选择所有三个按钮时,我想单击我的取消按钮,该按钮在视图上而不是在同一控制器上的表格中,以重新加载所有 3 行调用转到自定义单元格类,其中 uncheck 设置为 true 并重新加载行.第一次尝试它工作正常,我可以看到要重新加载的正确索引.第二次,当我选择所有 3 个复选按钮并再次单击取消时,我可以看到要重新加载的正确索引,但调用不会再次转到自定义单元格类,复选框仍保持选中状态.知道为什么吗?我总是在我的数组中获得正确的索引.

I have a table with 3 rows each with check button.What I am doing is when I select all the three buttons I want to click my cancel button which is on view not table on same controller to reload all 3 rows the call goes to custom cell class where uncheck is set to true and rows are reloaded.For the first attempt it works fine I can see correct index to be reloaded.On the second time again when I select all 3 check buttons and click cancel again I can see correct index to be reloaded but the call is not going to custom cell class again the check box still remains checked.Any idea why? I am always getting correct index in my array.

取消按钮代码-:

@IBAction func cancelDataItemSelected(_ sender: UIButton) {
    for index in selectedButtonIndex{
            let indexPath = IndexPath(item: index, section: 0)
            print(selectedButtonIndex)
            filterTableViewController.reloadRows(at: [indexPath], with: UITableViewRowAnimation.none)
    }
    selectedButtonIndex .removeAll()
    print(selectedButtonIndex)
}

表格代码-:

extension filterControllerViewController:UITableViewDataSource,UITableViewDelegate
{
    // NUMBER OF ROWS IN SECTION
     func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
      return ControllerData.count
     }

    // CELL FOR ROW IN INDEX PATH
     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
     let Cell = tableView.dequeueReusableCell(withIdentifier: "filterCell", for: indexPath) as! ControllerCellTableViewCell
    Cell.filterTableMenu.text = ControllerData[indexPath.item]
     Cell.radioButtonTapAction = {
     (cell,checked) in
     if let radioButtonTappedIndex =  tableView.indexPath(for: cell)?.row{
        if checked == true {
          self.selectedButtonIndex.append(radioButtonTappedIndex)
    }
        else{
            while self.selectedButtonIndex.contains(radioButtonTappedIndex) {
                if let itemToRemoveIndex = self.selectedButtonIndex.index(of: radioButtonTappedIndex) {
                    self.selectedButtonIndex.remove(at: itemToRemoveIndex)
                 }
              }
           }
        }
    }
     return filterCell
}

自定义类-:

var radioButtonTapAction : ((UITableViewCell,Bool)->Void)?
     //MARK-:awakeFromNib()
        override func awakeFromNib() {
            super.awakeFromNib()
            filterTableSelectionStyle()
            self.isChecked = false
        }

        // CHECKED RADIO BUTTON IMAGE
        let checkedImage = (UIImage(named: "CheckButton")?.withRenderingMode(UIImageRenderingMode.alwaysOriginal))! as UIImage
        // UNCHECKED RADIO BUTTON IMAGE
        let uncheckedImage = (UIImage(named: "CheckButton__Deselect")?.withRenderingMode(UIImageRenderingMode.alwaysOriginal))! as UIImage
        // Bool STORED property
        var isChecked: Bool = false {
            didSet{
                // IF TRUE SET TO CHECKED IMAGE ELSE UNCHECKED IMAGE
                if isChecked == true {
                  TableRadioButton.setImage(checkedImage, for: UIControlState.normal)
                } else {
                  TableRadioButton.setImage(uncheckedImage, for: UIControlState.normal)
                }
            }
        }
        // FILTER CONTROLLER RADIO BUTTON ACTION

        @IBAction func RadioButtonTapped(_ sender: Any) {
            isChecked = !isChecked
            radioButtonTapAction?(self,isChecked)
        }

推荐答案

对可重用"表格单元格工作原理的根本误解.

Fundamental misunderstanding of how "reusable" table cells work.

假设您的表格视图足够高,以至于只有 8 个单元格可见.很明显,需要创建8个单元格,滚动时会重复使用.

Let's say your table view is tall enough that only 8 cells are ever visible. It seems obvious that 8 cells will need to be created, and they will be reused when you scroll.

可能明显的是,单元在重新加载时会被重用.换句话说,每次 .reloadData 被调用时——即使你只重新加载一个当前可见的单元格——该单元格会被重用.它不是重新创建的.

What may not be obvious is that the cells also are reused when they are reloaded. In other words, every time .reloadData is called - even if you are only reloading one cell that is currently visible - that cell is reused. It is not re-created.

因此,关键要点是:任何初始化任务在首次创建单元格时发生.之后,单元格会被重用,如果您想要状态"条件 - 例如选中或未选中的按钮 - 您可以将单元格重置"为其原始状态.

So, the key takeaway point is: Any initialization tasks happen only when the cell is first created. After that, the cells are reused, and if you want "state" conditions - such as a checked or unchecked button - it is up to you to "reset" the cell to its original state.

正如所写,您的 cellForRowAt 函数只设置了 .filterTableMenu.text ... 它忽略了 .isChecked 状态.

As written, your cellForRowAt function only sets the .filterTableMenu.text ... it ignores the .isChecked state.

您可以通过设置单元格的 .isChecked 值来解决大部分问题,但您还需要以一种比需要复杂得多的方式跟踪开/关状态.而不是使用数组来附加/删除行索引,而是使用布尔数组,并且只使用 array[row] 来获取/设置值.

You can mostly fix things just by setting the cell's .isChecked value, but you're also tracking the on/off states in a much more complicated manner than need be. Instead of using an Array to append / remove row indexes, use an Array of Booleans, and just use array[row] to get / set the values.

然后你的 cellForRowAt 函数看起来像这样:

Then your cellForRowAt function will look about like this:

// CELL FOR ROW IN INDEX PATH
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let filterCell = tableView.dequeueReusableCell(withIdentifier: "filterCell", for: indexPath) as! ControllerCellTableViewCell

    // set the label in filterCell
    filterCell.filterTableMenu.text = ControllerData[indexPath.item]

    // set current state of checkbox, using Bool value from out "Tracking Array"
    filterCell.isChecked = self.selectedButtonIndex[indexPath.row]

    // set a "Callback Closure" in filterCell
    filterCell.radioButtonTapAction = {
        (checked) in
        // set the slot in our "Tracking Array" to the new state of the checkbox button in filterCell
        self.selectedButtonIndex[indexPath.row] = checked
    }

    return filterCell

}

您可以在这里看到一个工作示例:https://github.com/DonMag/CheckBoxCells

You can see a working example here: https://github.com/DonMag/CheckBoxCells

这篇关于filterTableViewController.reloadRows 仅在第一次调用时重新加载行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆