Ios 如何从UITableView重用单元

Ios 如何从UITableView重用单元,ios,swift,uitableview,cell,Ios,Swift,Uitableview,Cell,我有一个UITableView,其中每个单元格都有一个图像。每当我选择一个单元格时,我都会更改当前单元格的图像。但当我滚动单元格时,一个或多个单元格消失了,单元格会被重新创建或重新创建,默认图像会再次出现。我希望更改后的图像保留在单元格中,直到视图卸载或消失 这是我的UITableView代理 //UITableview delegate func numberOfSectionsInTableView(tableView: UITableView) -> Int { return

我有一个
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")
        }
    }
}

你在这里看到的是视图回收。这使得
UITableView
速度更快,占用的内存更少

您应该将“选中”状态逻辑与单元格分开

向类中添加一个属性,该属性存储选中的
indepath

var checkedIndexPath:NSIndexPath?
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")  
    }
}
然后将所选索引保存在
checkedIndexPath

var checkedIndexPath:NSIndexPath?
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")  
    }
}
要启用单元重用(并提高内存消耗和性能),请更改此行:

let cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "Cell")
cell.imageView?.image = UIImage(named: "Ingr_Uncheck")
致:

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

let 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")
}

这样,视图控制器代码将更加清晰。您可以重写单元格中的
prepareforeuse
方法,以便在重新使用之前重置为默认状态。要检查选定的单元格,可以使用
tableView.indexpathsforelectedrows
获取选定索引的列表。

Hi@redent84感谢您的回复。我把let电池换成了你建议的,但没用。对于看不见的单元格,图像仍然设置为默认值(向外滚动)。问题是您没有在
cellForRow
上设置图像,而是在
didSelectRow
中设置图像。查看我的编辑以查看管理单元格选择的更简单方法。我找不到名为setSelected@redent84的func此方法::哦,我知道了,但我无法从多个类继承。我已经从UIViewController继承了。