Table View Cells Changing Colors When Scrolling Swift

First and Last Cell Change Color When Scrolling in UITableView

Cells are reused...

That means, when you scroll down and then back up, you can get a cell that had its background color changed to red while it was at, say, row 20, but now is being used for row 0.

You need to explicitly set the desired background color in cellForRowAt every time.

EDIT

You can use your current method of changing the background color, but you'll have to track the current background color as part of your dataSource.

For example, add a currentBackgroundColor property to your Person class. When you do this:

// update text of cell and check some conditions to set the gradient of the cell accordingly

you would also do (something like):

data[indexPath.section].currentBackgroundColor = UIColor.green

When you get a call to cellForRowAt, you would then also do:

cell.backgroundColor = data[indexPath.section].currentBackgroundColor

Without seeing your actual data source / structure, it's difficult to give you an explicit example, but that's the idea.

UITableView's Items Change Color After Scrolling Down, Then Back Up Swift

The cellForRowAt method is not a for loop!

I see that you are using a tag property to control what gets shown in each cell. From the fact that you increment the tag very time cellForRowAt is called, you seem to assume that cellForRowAt will be called once for each row, in order. This is not the case, and you should not implement cellForRowAt like this.

cellForRowAt essentially asks a question: "What should the cell at this index path be?", and you provide the answer. The index path that the table view is asking about is the indexPath parameter. You should make use of this parameter instead of your own tag property, because the table view is not asking about that.

The reason why why your code doesn't work is because table view cells are reused. When cells are scrolled out of view, they are not put aside, so that when new table view cells need to be shown, they can be reconfigured to "appear as if they are new cells". Essentially what this means is that when you scroll up, cellForRowAt is called for the rows that are about to come into view. You didn't expect that, did you?

All that code that sets up each cell should be moved to the initialiser of ThemeCell. Alternatively, design the cell in a storyboard. cellForRowAt should only configure a cell specifically for an index path. ThemeCell should have the properties cellButton and cellyi so that the buttons can be accessed.

Now, cellForRowAt can be written like this:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCell(withIdentifier: "themeCell", for: indexPath) as! ThemeCell

cell.cellButton.setImage(UIImage(named: SingletonViewController.themes[indexPath.row]), for: UIControl.State.normal)
cell.cellButton.addTarget(self, action: #selector(CustomViewController.backBTN(sender:)), for: .touchUpInside)

cell.cellyi.addTarget(self, action: #selector(CustomViewController.backBTN(sender:)), for: .touchUpInside)

if UserDefaults.standard.integer(forKey: "like") == indexPath.row {
cell.cellyi.backgroundColor = UIColor.green
} else {
cell.cellyi.backgroundColor = UIColor.red
}

// this line should be moved to viewDidLoad
// tableView.allowsSelection = false
return cell
}

Swift Table View Cell changes gradient Color after scrolling

The issue could be caused by the fact that a new gradient layer is inserted every time setGradientBackground is called.

To avoid that check if the layer exists. If it exists update the colors otherwise create the new layer.

func setGradientBackground(colorOne: UIColor, colorTwo: UIColor, bounds_object: UIView){

if let gradientLayer = layer.sublayers?.first as? CAGradientLayer {
gradientLayer.colors = [colorOne.cgColor, colorTwo.cgColor]
} else {
let gradientLayer = CAGradientLayer()
gradientLayer.frame = bounds_object.bounds
gradientLayer.colors = [colorOne.cgColor, colorTwo.cgColor]
gradientLayer.locations = [0.0, 1.0]
gradientLayer.startPoint = CGPoint(x: 1.0, y: 1.0)
gradientLayer.endPoint = CGPoint(x: 0.0, y: 0.0)
layer.insertSublayer(gradientLayer, at: 0)
}
}

Actually prepareForReuse() is redundant because you can set image and text in the last else scope. It makes sure that all UI elements are set to a defined state.

Add these two lines and delete the entire prepareForReuse() method in GroupCell.

else {
cell.bgView.setGradientBackground(colorOne: UIColor.lightGray
, colorTwo: UIColor.white, bounds_object: cell.bgView)
cell.iconImageView.image = nil
cell.groupLabel.text = ""
}

A better syntax than if - else if in this case is a switch

switch indexPath.row {
case 0:
cell.bgView.setGradientBackground(colorOne: UIColor.white
, colorTwo: KitaGruppen.Spatzen().color, bounds_object: cell.bgView)
cell.groupLabel!.text = "Spatzen"
cell.iconImageView?.image = UIImage(named: "SpatzIcon")

case 1:

cell.bgView.setGradientBackground(colorOne: UIColor.white
, colorTwo: KitaGruppen.Elefanten().color, bounds_object: cell.bgView)
cell.groupLabel!.text = "Elefanten"
cell.iconImageView?.image = UIImage(named: "elefantIcon")

...

default:
cell.bgView.setGradientBackground(colorOne: UIColor.lightGray
, colorTwo: UIColor.white, bounds_object: cell.bgView)
cell.iconImageView.image = nil
cell.groupLabel.text = ""
}

UITableView Cell Background Color Collapse when Scroll

It may happening because you have not cleared the cell in prepareForReuse:

override func prepareForReuse() {
super.prepareForReuse();

// Do the minor cleanup that is needed to reuse the cell
self.contentView.backgroundColor = .clear;
self.customAccessoryView.backgroundColor = .clear;
}

In the cellForRowAtIndexpath

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "supportedServicesCell", for: indexPath) as? SupportedServicesTableViewCell else { fatalError("Supported Services Cell Error")}
guard let data = self.dataSource else { return cell }
cell.cell_data = data[indexPath.row]
if(indexPath.row % 2 == 0){
cell.contentView.backgroundColor = Color.SupportedServicesTable.cellGray
cell.customAccessoryView.backgroundColor = Color.SupportedServicesTable.accessoryGray
cell.containerView.backgroundColor = Color.SupportedServicesTable.accessoryGray // Set the color you want
}else{
cell.containerView.backgroundColor = UIColor.white
cell.customAccessoryView.backgroundColor = Color.SupportedServicesTable.cellGray
cell.contentView.backgroundColor = .white // Set the color you want
}
return cell
}
}

TextLabel colour automatically changed when i Scroll UiTableView

First you have to create property to hold selected cell like below

/* To hold selected cell */
var selectedIndexPath :IndexPath?

After that set color of selected cell in cellForRowAt

 override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

if let cell = tableView.dequeueReusableCell(withIdentifier: "cell") {
cell.textLabel?.text = "Row Number: \(indexPath.row)"

/* Check if cell is selected then set layout accourding to your requirements */
if indexPath == selectedIndexPath {
cell.textLabel?.textColor = .blue
} else {
cell.textLabel?.textColor = .black
}
return cell
}

return UITableViewCell()
}

After this manage when user select a cell in didSelectRowAt

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// Toggle if user seleted same cell
if selectedIndexPath == indexPath {
if let cell = tableView.cellForRow(at: indexPath) {
/* Check and toggle selected cell color */
cell.textLabel?.textColor = cell.textLabel?.textColor == .black ? .blue : .black
}
} else {
/* set color of seleted cell */
if let cell = tableView.cellForRow(at: indexPath) {
cell.textLabel?.textColor = .blue
}
}

/* Save which cell is selected */
selectedIndexPath = indexPath
}

And last manage didDeselectRowAt

override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {

/* Remove if deselect same cell */
if selectedIndexPath == indexPath {
selectedIndexPath = nil
}
/* Change color to black */
if let cell = tableView.cellForRow(at: indexPath) {
cell.textLabel?.textColor = .black
}
}

This code is for on cell selection at one time so you have to set

tableView.allowsMultipleSelection = false

Hope this helps.

Selection of UITableViewCell Changes when Scroll down in Swift

cellForRowAt will be called every time that cell is displayed.
you need selected list to save selected index.

var listSelected: [Int] = []

and

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCell(withIdentifier: "TasksTableViewCell") as! TasksTableViewCell

cell.backView.backgroundColor = listSelected.contains(indexPath.row) ? UIColor(named: "primaryViewColor") : .white

return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if listSelected.contains(indexPath.row) {
listSelected = listSelected.filter{$0 != indexPath.row}
} else {
listSelected.append(indexPath.row)
}

tableView.reloadRows(at: [indexPath], with: .automatic)

}

UIView background color in Custom TableView only change when scrolled, why?

Hey guys i found the solution to fix my problem, because the cell is not created yet fully in the first load so we need to add "willDisplay cell"

so i add this code:

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {

if let cell = cell as? ExceptionalTableViewCell {
cell.containerHeader.backgroundColor = UIColor(named: "Cinderella")
cell.lblStatusApprove.textColor = UIColor(named: "Carnation")
}
}


Related Topics



Leave a reply



Submit