Reputation: 4166
I have the strangest glitch after I select a UITableView cell and scroll away(You can see it here):
When I select a cell, it's programmed to change its text and change the font color from brown to red. However, when I scroll, other cells that I have not selected change their font color to red. And when I scroll back to the selected cell it reverts to its original text and sometimes, its font color too (from red to brown).
I've used this post in attempt to fix it. But still the glitch remains.
I am completely baffled as to why this is happening and would love love love if anyone could tell me why.
In my code I made my ViewController CategoryViewController
the UITableView
's Datasource
& Delegate
instead of a UITableViewController
b/c I have other views in my CategoryViewController
, not just a UITableView
class CategoryViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
private let themeColors = ThemeColors()
private let expensesOrganizer = ExpensesOrganizer()
override func viewDidLoad() {
super.viewDidLoad()
//Set up subCategory table view
subCategoryTableView.dataSource = self
subCategoryTableView.delegate = self
}
// MARK: UITableViewDataSource
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return expensesOrganizer.getNumOfSubcategoriesFor(category!)
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let subcategoryCell = tableView.dequeueReusableCellWithIdentifier("subCategoryCell", forIndexPath: indexPath) as! SubcategoryTableViewCell
let subcategory = expensesOrganizer.getSubcategoryFor(category!, index: indexPath.row)
subcategoryCell.subCategoryLabel.text = "\(indexPath.row) \(expensesOrganizer.getText(subcategory.rawValue))"
subcategoryCell.selectedBackgroundView = UIView(frame: CGRect.zero)
subcategoryCell.selectedBackgroundView?.backgroundColor = themeColors.getColorOfCategory(category!)
return subcategoryCell
}
// MARK: UITableViewDelegate
var indexPathSelectedCell: NSIndexPath?
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let subcategoryCell = tableView.cellForRowAtIndexPath(indexPath) as! SubcategoryTableViewCell
subcategoryCell.subCategoryLabel.textColor = UIColor.redColor()
subcategoryCell.subCategoryLabel.text = "\(indexPath.row) didSELECTRowAtIndexPath called"
indexPathSelectedCell = indexPath
//What the post said to add:
let selectedRows = subCategoryTableView.indexPathsForSelectedRows
for i in selectedRows! {
if !i.isEqual(indexPath){
subCategoryTableView.deselectRowAtIndexPath(i, animated: false)
}
}
}
func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
let subcategoryCell = tableView.cellForRowAtIndexPath(indexPath) as! SubcategoryTableViewCell
subcategoryCell.subCategoryLabel.textColor = themeColors.getFontColor(Shade.Light)
subcategoryCell.subCategoryLabel.text = "\(indexPath.row) didDESELECTRowAtIndexPath called"
}
Upvotes: 0
Views: 1478
Reputation:
This has to do with cell reuse.
When you change the color of the label in didSelectRowAtIndexPath
, then scroll that cell off-screen, it gets reused for a different cell that will appear on-screen.
However, since you don't prepare the cell for reuse, it is still using the selected font color for your label.
Assigning the label's default text color in prepareForReuse
or cellForRowAtIndexPath
will fix this issue.
Upvotes: 0
Reputation: 727077
The approach that you take is incorrect, because you are not setting the color when you reuse a cell. Your cellForRowAtIndexPath
needs to set color back to brown if the cell is not selected. It should be set to red if the cell is selected:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let subcategoryCell = tableView.dequeueReusableCellWithIdentifier("subCategoryCell", forIndexPath: indexPath) as! SubcategoryTableViewCell
let subcategory = expensesOrganizer.getSubcategoryFor(category!, index: indexPath.row)
subcategoryCell.subCategoryLabel.text = "\(indexPath.row) \(expensesOrganizer.getText(subcategory.rawValue))"
subcategoryCell.selectedBackgroundView = UIView(frame: CGRect.zero)
subcategoryCell.selectedBackgroundView?.backgroundColor = themeColors.getColorOfCategory(category!)
if let selected = tableView.indexPathsForSelectedRows() as? [NSIndexPath] && selected! == indexPath {
subcategoryCell.subCategoryLabel.textColor = UIColor.brownColor()
} else {
subcategoryCell.subCategoryLabel.textColor = UIColor.redColor()
}
return subcategoryCell
}
Upvotes: 2