Reputation: 47
I am just starting with delegates in Swift. I have a collectionView that will be populated with specifc cells. Every cell will have a like button were a user can press it, every press should toggle between two different heart images. I have setup the delegate and its protocol in the cell class. I call the delegate in the view controller class that holds the collection of the cells. How I am supposed to change the specific cell's heart-button-image if it does not let me reference the cell and its properties? Thank you!!
I obviously have tried calling the IB Action heart-button-image variable, no luck. do I need to just merge my delegate with the: "func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell" function? This does of course allow you to reference the specific cell but it seems like the wrong approach.
CUSTOM CELL CLASS THAT HOLDS DELEGATE INITILIZATION:
protocol EventCellDelegate: class {
func likeButtonPressed(toggle: Int)
}
class ProfileEventCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var likeCount: UILabel!
@IBOutlet weak var friendsGoing: UILabel!
@IBOutlet weak var friendGoingPic: UIImageView!
@IBOutlet weak var eventName: UILabel!
@IBOutlet weak var eventDate: UILabel!
@IBOutlet weak var eventTime: UILabel!
@IBOutlet weak var eventOrg: UILabel!
@IBOutlet weak var eventPic: UIImageView!
@IBOutlet weak var eventPrice: UIButton! // WHERE THE HEART IMAGE GOES (bad name sorry)
weak var delegate: EventCellDelegate?
var likeToggle = 1
/*
let redHeart = UIImage(named: "likeheart")
let grayHeart = UIImage(named: "unlikeheart")
var likeToggle = 1
var likeCountValue = 347
*/
@IBAction func eventPricePressed(_ sender: UIButton) {
delegate?.likeButtonPressed(toggle: 1)
}
}
DELEGATE FUNCTION INSIDE MY HOME VIEW CONTROLLER CLASS:
extension HomeViewController: EventCellDelegate {
func likeButtonPressed(toggle: Int) {
//ProfileEventCollectionViewCell.eventPrice <-- doesnt allow
likeToggle = likeToggle + toggle <-- doesnt find
likeToggle
if (likeToggle % 2 == 0) {
eventPrice.setImage(redHeart, for: .normal)
//likeCountValue = likeCountValue + 1
} else {
eventPrice.setImage(grayHeart, for: .normal)
//likeCountValue = likeCountValue - 1
}
}
}
Instance member 'eventPrice' cannot be used on type 'ProfileEventCollectionViewCell'
Use of unresolved identifier 'likeToggle'
Upvotes: 0
Views: 668
Reputation: 114826
Your delegate function needs to pass the cell in which the like button was pressed:
protocol EventCellDelegate: class {
func likeButtonPressed(in cell: ProfileEventCollectionViewCell)
}
Then you can call the delegate function as:
@IBAction func eventPricePressed(_ sender: UIButton) {
delegate?.likeButtonPressed(in:self)
}
You don't need to pass the toggle
value - The view controller can decide what it needs to do when the button is tapped.
I wouldn't update the cell directly in the delegate method; Update your data model and then reload the cell - your cellForItemAt:
can handle the appearance update.
And your implementation of the delegate function will be something like:
func likeButtonPressed(in cell:ProfileEventCollectionViewCell) {
guard let indexPath = self.collectionView.indexPath(for: cell) else {
return
}
let myObject = myDataSource[indexPath.item]
myObject.liked.toggle
self.collectionView.reloadItems(at: [indexPath])
}
Upvotes: 0