Reputation: 1352
I have a custom collection view with a mark favorite button at the top which when pressed should show a Instagram like heart animation at the center. What I have done so far causes the heart animation to appear in some other random cells of course that is due to this code of reusing identifier.
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "shopCell", for: indexPath) as! ShopCell
but how should I resolve this issue? I have read multiple posts about it and implemented the solution but none of them worked for me. For example setting index path to cell and after that using delegation on button click
cell.indexPath = indexPath
and in my shop cell I have
@IBAction func favHeartBtn(_ sender: Any) {
delegate.favoriteButton(sender: self)
}
In my shopView I have this
func favoriteButton(sender: ShopCollectionViewCell) {
sender.centerHeart.isHidden = false
sender.centerHeart.zoomIn()
}
Still animation starts in other cells. Even if I put a check for indexPath
Upvotes: 0
Views: 1324
Reputation: 1352
Although PGDev answer was perfect and I accepted it as the right answer. The issue which was causing the PGDev code to not work in my custom class was that I was using delegation for the button.
cell.delegate = self
I removed this line and added the code for the animation which PGDev has provided in the cell IBOutlet for the button and this did the trick.
Upvotes: 0
Reputation: 24341
You need to handle the show/hide of the center heart in your custom UICollectionViewCell
, i.e.
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
})
}
}
}
}
You can add whatever animation you need according to your requirement.
Sample Project: https://github.com/pgpt10/CollectionViewSample
Upvotes: 1
Reputation: 229
In your class create array with indexes:
var favoriteList = [Int]()
In cell setup code you set button’s tag to the indexPath.row
[skip cell setup code]
cell.centerHeart.tag = indexPath.row
Your favoriteButton will look like:
func favoriteButton(sender: ShopCollectionViewCell) {
///update model
favoriteList.append(sender.tag)
///refresh UI
self.tableView.reloadData()
}
In this delegate you check IndexPath. And if you found this indexPath in list, you show button.
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)
}
And for cell you implement:
func displayCenterHearth() {
self.centerHeart.isHidden = false
self.centerHeart.zoomIn()
}
func hideCenterHearth() {
self.centerHeart.isHidden = true
}
This solution should work for you. Sorry for possible mistakes, I have used TextEditor to write this code.
What is major issue of the original solution. We are using MVC. And it means that we have model and view. When you press button, you update your UI (view) but you don't do anything with your data model. Right scenarios is: update model and reload or refresh view.
I believe you already have data model and it looks like:
var model: [Record]
struct Record {
var title: String
var description: String
var isFavorite: Bool
}
To make it works with your data model, set isFavorite property to true in delegate method and rewrite 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
}
Upvotes: 0