快速收集视图按钮影响其他单元格



我有一个自定义集合视图,上面有一个标记喜欢的按钮,当按下时应显示一个中心的Instagram,例如心脏动画。到目前为止,我所做的事情导致心脏动画出现在其他一些随机单元中,这当然是由于这种重复使用标识符的代码。

let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "shopCell", for: indexPath) as! ShopCell

但是我应该如何解决这个问题?我已经阅读了多个有关它的文章并实施了解决方案,但它们都不适合我。例如,将索引路径设置为单元格,然后使用委派在按钮上单击

cell.indexPath = indexPath

,在我的商店单元中,我有

@IBAction func favHeartBtn(_ sender: Any) {
    delegate.favoriteButton(sender: self)
}

在我的Shopview中,我有这个

func favoriteButton(sender: ShopCollectionViewCell) {  
    sender.centerHeart.isHidden = false
    sender.centerHeart.zoomIn()
}

仍然动画从其他单元格开始。即使我对IndexPath进行检查

您需要在自定义UICollectionViewCell中处理中心心脏的表演/隐藏,即

class CustomCollectionCell : UICollectionViewCell
{
    @IBOutlet weak var centerHeart: UILabel!
    override func awakeFromNib()
    {
        super.awakeFromNib()
        self.centerHeart.alpha = 0.0
    }
    @IBAction func onTapHeartButton(_ sender: UIButton)
    {
        UIView.animate(withDuration: 0.5, animations: { 
            self.centerHeart.alpha = 1.0
        }) { (completed) in
            if completed
            {
                UIView.animate(withDuration: 0.5, animations: { 
                    self.centerHeart.alpha = 0.0
                })
            }
        }
    }
}

您可以根据需要添加所需的任何动画。

示例项目: https://github.com/pgpt10/collectionviewsample

在您的班级中创建索引:

var favoriteList = [Int]()

在单元格代码中,您将按钮的标签设置为indexpath.row

[skip cell setup code]
cell.centerHeart.tag = indexPath.row 

您最喜欢的按钮看起来像:

func favoriteButton(sender: ShopCollectionViewCell) {
    ///update model
    favoriteList.append(sender.tag)
    ///refresh UI
    self.tableView.reloadData()
}

在此代表中,您检查IndExpath。而且,如果您在列表中找到此Indexpath,则显示按钮。

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    if self.shouldAnimateCell(indexPath) {
        cell.showHearthAnimation(indexPath)
    } else {
        cell.hideHearthAnimation()
    }   
}

func showHearthAnimation(indexPath: IndexPath) {
    let cell = self.tableView.cellForRow(indexPath)
    cell.displayCenterHearth()
}
func hideHearthAnimation(indexPath: IndexPath) {
    let cell = self.tableView.cellForRow(indexPath)
    cell.hideCenterHearth()
}
func shouldAnimateCell(indexPath: IndexPath) {
    return self.favoriteList.contains(indexPath.row)
}

和您实现的单元格:

func displayCenterHearth() {
    self.centerHeart.isHidden = false
    self.centerHeart.zoomIn()
}
func hideCenterHearth() {
    self.centerHeart.isHidden = true
}

此解决方案应该对您有用。抱歉,可能的错误,我已经使用了Texteditor编写此代码。


原始解决方案的主要问题是什么。我们正在使用MVC。这意味着我们有模型和观点。按下按钮时,您会更新UI(视图),但是您对数据模型无能为力。正确的方案是:更新模型和重新加载或刷新视图。

我相信您已经有数据模型,看起来像:

var model: [Record]
struct Record {
    var title: String
    var description: String
    var isFavorite: Bool
}

为了使其与您的数据模型一起使用,请将iSfavorite属性设置为true in eyegate方法,然后重写shordanimatecell。

func favoriteButton(sender: ShopCollectionViewCell) {
    ///update model
    let indexPath = self.tableView.indexPath(for: sender)
    self.model[indexPath.row].isFavorite = true
    ///refresh UI
    self.tableView.reloadData()
}
func shouldAnimateCell(indexPath: IndexPath) {
    return self.model[indexPath.row].isFavorite
}

尽管PGDEV答案是完美的,但我接受了正确的答案。导致PGDEV代码在我的自定义类中不起作用的问题是我正在使用该按钮的委托。

cell.delegate = self

我删除了此行,并为PGDEV在iboutlet中为按钮提供的动画添加了代码。

最新更新