When I tap a button in a custom cell and then scroll down (or up) another cell button is also tapped. I see that it's tapped because the button outlet that I created for the button is disabled.
My cellForRowAtIndexPath
has a reuseIdentifier for the cell:
var cell: FeedTableViewCell? = tableView.dequeueReusableCellWithIdentifier("MusicCell") as? FeedTableViewCell
Considering I have the degueueReusableCellWithId
in the cellForRowAtIndexPath
do I need a prepareForReuse
? When I add the prepareForReuse
in my custom cell file, the cell just goes back to the default values (obviously because I reset it to the default values). Problem is I want it to keep the value of each indexPath.row.
This is how I'm querying the values:
override func queryForTable() -> PFQuery {
var query:PFQuery = PFQuery(className:"Music")
if(objects?.count == 0)
{
query.cachePolicy = PFCachePolicy.CacheThenNetwork
}
query.orderByAscending("videoId")
return query
}
This is the numberOfRowsInSection
and cellForRowAtIndexPath
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return objects!.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject?) -> PFTableViewCell? {
var cell: FeedTableViewCell? = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as? FeedTableViewCell
if(cell == nil) {
cell = NSBundle.mainBundle().loadNibNamed("FeedTableViewCell", owner: self, options: nil)[0] as? FeedTableViewCell
}
if let pfObject = object {
//I took out the irrelevant methods. I can add them if that makes a difference...
var votes:Int? = pfObject["votes"] as? Int
if votes == nil {
votes = 0
}
cell?.votesLabel?.text = "\(votes!)"
}
I'm registering this in the viewDidLoad
above the super.viewDidLoad()
tableView.registerNib(UINib(nibName: "FeedTableViewCell", bundle: nil), forCellReuseIdentifier: cellIdentifier)
This is my button query in the customCell:
@IBAction func heartButton(sender: AnyObject) {
if(parseObject != nil) {
if var votes:Int? = parseObject!.objectForKey("votes") as? Int {
votes!++
parseObject!.setObject(votes!, forKey: "votes")
parseObject!.saveInBackground()
votesLabel?.text = "\(votes!)"
}
}
heartOutlet.enabled = false
}
Any help and suggestions mean a lot.
Thank you.
REFRENCE LINKS I USED:
I referred to several links but they were in objective-c and didn't help:
UICollectionView Tap Selects More Than One Cell
How to use prepareForReuse method
I also referred to the docs, and that didn't help much.
From the code you have posted, it is clear that you are not setting the enabled
property of the UIButton
with respect to the DataSource
(The array and its objects you are using to load the tableview, that is the elements in objects
array). Whatever objects that array contains, add a property to determine if the condition for the button should be true or false, and then in cellForRowAtIndexPath
set the enabled property of the button according to that. When the button is clicked, add a callback to the ViewController(using a delegate) and set the property there.
Sample Code
In custom cell class:
protocol CellButtonDelegate
{
func buttonClicked(cell : PFTableViewCell)
}
public var delegate : CellButtonDelegate?
public var buttonEnabled : Bool?
{
get
{
return heartOutlet.enabled
}
set
{
heartOutlet.enabled = newValue
}
}
@IBAction func heartButton(sender: AnyObject) {
if(parseObject != nil) {
if var votes:Int? = parseObject!.objectForKey("votes") as? Int {
votes!++
parseObject!.setObject(votes!, forKey: "votes")
parseObject!.saveInBackground()
votesLabel?.text = "\(votes!)"
}
}
delegate?.buttonClicked(self)
}
In ViewController:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject?) -> PFTableViewCell? {
var cell: FeedTableViewCell? = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as? FeedTableViewCell
if(cell == nil) {
cell = NSBundle.mainBundle().loadNibNamed("FeedTableViewCell", owner: self, options: nil)[0] as? FeedTableViewCell
}
if let pfObject = object {
//I took out the irrelevant methods. I can add them if that makes a difference...
var votes:Int? = pfObject["votes"] as? Int
if votes == nil {
votes = 0
}
cell?.buttonEnabled = objects[indexPath.row].isEnabled //The new property you need to add. true by default
cell?.delegate = self //Make sure you implement the delgate
cell?.votesLabel?.text = "\(votes!)"
return cell?
}
func buttonClicked(cell : PFTableViewCell)
{
//Here, get the indexPath using the cell and assign the new property in the array.
}
Please note that the above code is rough. Just get the idea from the code and implement it as per your requirement.