【问题标题】:How to reuse cell from an UITableView如何重用 UITableView 中的单元格
【发布时间】:2015-12-10 16:44:41
【问题描述】:

我有一个UITableView,其中每个单元格都有一个图像。每当我选择其中一个单元格时,我都会更改当前单元格的图像。但是当我滚动并且单元格或单元格消失时,单元格会被重新创建或重新创建,并且默认图像再次出现。我希望更改后的图像保留在单元格上,直到视图卸载或消失。

这是UITableView 的代表。

//UITableview delegate
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return Arecipe.IngredientArr.count
}

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return UITableViewAutomaticDimension;
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    if(tableView == IngrediensTableView || tableView == ProcedureTableView)
    {
        print("Cell")

        let cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "Cell")
        let ingredient = self.Arecipe.IngredientArr[indexPath.row]

        cell.textLabel?.text = ingredient.UnitValue + " " + ingredient.UnitName + " " + ingredient.Name
        cell.imageView?.image = UIImage(named: "Ingr_Uncheck")
        cell.selectionStyle = .None

        return cell
    }

    return UITableViewCell()
}

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    print("Row \(indexPath.row) selected")

    if(tableView == IngrediensTableView || tableView == ProcedureTableView)
    {
        let cell: UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!

        if(cell.imageView?.image == UIImage(named: "Ingr_Uncheck"))
        {
            cell.imageView?.image = UIImage(named: "Ingr_Check")
        }
        else
        {
            cell.imageView?.image = UIImage(named: "Ingr_Uncheck")
        }
    }
}

【问题讨论】:

    标签: ios swift uitableview cell


    【解决方案1】:

    您在此处看到的是视图回收。这使UITableView 速度更快并使用更少的内存。

    您应该将“已检查”状态逻辑与单元格分开。

    向您的类添加一个属性,用于存储选中的IndexPath

    var checkedIndexPath:NSIndexPath?
    

    然后将选中的索引保存在checkedIndexPath

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        let previousChecked = checkedIndexPath
        checkedIndexPath = indexPath    
        tableView.reloadRowsAtIndexPaths([previousChecked, checkedIndexPath], withRowAnimation:.Automatic)
    }
    
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath)
        if indexPath == checkedIndexPath {
            cell.imageView?.image = UIImage(named: "Ingr_Check")        
        }
        else {
            cell.imageView?.image = UIImage(named: "Ingr_Uncheck")  
        }
    }
    

    【讨论】:

      【解决方案2】:

      要启用单元重用(并提高内存消耗和性能),请更改此行:

      let cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "Cell")
      

      收件人:

      let cell = tableView.dequeueReusableCellWithIdentifier("Cell")
              ?? UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "Cell")
      

      要刷新单元格重用的选择状态,请更改此行:

      cell.imageView?.image = UIImage(named: "Ingr_Uncheck")
      

      到这里:

      let selected = (tableView.indexPathsForSelectedRows ?? []).contains(indexPath)
      cell.imageView?.image = UIImage(named: selected ? "Ingr_Check" : "Ingr_Uncheck")
      

      这样您将重复使用看不见的单元格,并根据单元格的选择状态刷新图像。

      我建议您继承 UITableViewCell 并将“图像选择”逻辑移动到单元格的 setSelected 方法。像这样的:

      override func setSelected(selected: Bool, animated: Bool) {
          super.setSelected(selected, animated: animated)
          imageView?.image = UIImage(named: selected ? "Ingr_Check" : "Ingr_Uncheck")
      }
      

      这样视图控制器代码会更简洁。您可以在单元格中覆盖 prepareForReuse 方法以在重用之前重置为默认状态。要检查哪些单元格被选中,您可以使用tableView.indexPathsForSelectedRows 获取选中索引的列表。

      【讨论】:

      • 嗨@redent84 感谢您的回复。我将 let 单元格更改为您建议的内容,但它不起作用。对于看不见的单元格,图像仍会设置为默认值(滚动)。
      • 问题是你没有在cellForRow上设置图片,而是在didSelectRow上。查看我的编辑以了解管理单元格选择的更简单方法。
      • 我找不到名为 setSelected @redent84 的函数
      • 哦,我明白了,但我不能从多类继承。我已经从 UIViewController 继承了。
      猜你喜欢
      • 1970-01-01
      • 2018-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-17
      相关资源
      最近更新 更多