Swift collection 查看按钮影响其他单元格
Swift collection view button affecting other cells
我有一个自定义 collection 视图,顶部有一个标记收藏夹按钮,按下该按钮时应该会在中心显示一个类似 Instagram 的心形动画。到目前为止,我所做的导致心脏动画出现在其他一些随机单元格中,当然这是由于重用标识符的代码。
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "shopCell", for: indexPath) as! ShopCell
但是我该如何解决这个问题呢?我已经阅读了多篇关于它的文章并实施了解决方案,但其中 none 对我有用。例如,将索引路径设置为单元格,然后在单击按钮时使用委托
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
在您的 class 中创建具有索引的数组:
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 并重写 shouldAnimateCell。
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
}
您需要在自定义 UICollectionViewCell
中处理中心心的 show/hide,即
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
})
}
}
}
}
您可以根据需要添加任何您需要的动画。
虽然 PGDev 的答案很完美,但我还是接受了它作为正确答案。导致 PGDev 代码在我的自定义 class 中不起作用的问题是我正在为按钮使用委托。
cell.delegate = self
我删除了这一行并添加了 PGDev 在单元格 IBOutlet 中为按钮提供的动画代码,这成功了。
我有一个自定义 collection 视图,顶部有一个标记收藏夹按钮,按下该按钮时应该会在中心显示一个类似 Instagram 的心形动画。到目前为止,我所做的导致心脏动画出现在其他一些随机单元格中,当然这是由于重用标识符的代码。
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "shopCell", for: indexPath) as! ShopCell
但是我该如何解决这个问题呢?我已经阅读了多篇关于它的文章并实施了解决方案,但其中 none 对我有用。例如,将索引路径设置为单元格,然后在单击按钮时使用委托
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
在您的 class 中创建具有索引的数组:
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 并重写 shouldAnimateCell。
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
}
您需要在自定义 UICollectionViewCell
中处理中心心的 show/hide,即
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
})
}
}
}
}
您可以根据需要添加任何您需要的动画。
虽然 PGDev 的答案很完美,但我还是接受了它作为正确答案。导致 PGDev 代码在我的自定义 class 中不起作用的问题是我正在为按钮使用委托。
cell.delegate = self
我删除了这一行并添加了 PGDev 在单元格 IBOutlet 中为按钮提供的动画代码,这成功了。