I have an String array like [1,2,3,4,5]. I am displaying this array in tableview. My Question is If I want to change the color of 3rd cell only, How can I compare 3rd element with array in ios swift?
on your tableview delegate method based on the condition change the color what you want
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
cell.backgroundColor = indexPath.row == 2 ? .red : yellow //or use cell.contentView.backgroundColor = = indexPath.row == 2 ? .red : yellow
}
if you want to change the array contains 3 condition based then use like
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
cell.backgroundColor = yourArrayName[indexPath.row] == "3" ? .red : yellow //or use cell.contentView.backgroundColor = = yourArrayName[indexPath.row] == "3" ? .red : yellow
}
okay we go with alternate way
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
cell.backgroundColor = .yellow
if let index = yourArrayName.index(of: "3") {
cell.backgroundColor = indexPath.row == index ? .red : yellow
}
}
You can check the condition inside your cellforrow function like this too :
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ExampleCellIndentifier", for: indexPath) as! ExampleCell
if indexPath.row == 2{
// Do your modification on the 3rd cell item
cell.backgroundColor = .red
}
return cell
}
I just applied condition under cellForRowAt
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TextFieldInTableViewCell") as! myProfieTabelViewCellTableViewCell
if indexPath[1] % 2 == 0{
cell.backgroundColor = #colorLiteral(red: 0.9088078997, green: 0.9088078997, blue: 0.9088078997, alpha: 1)
print(indexPath[1])
}
else{
cell.backgroundColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
}
cell.selectionStyle = .none
return cell
}
I made an app that lists items in a UITableView. When I select items and scroll down till they go off screen, they will become visually deselected, meaning:
The checkbox image we set and the backgroundcolor are reset to original state.
The system itself however, does actually know what was selected and what wasnt.
Code:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:TblCell! = self.tableView.dequeueReusableCellWithIdentifier("cell") as TblCell!
cell.lblCarName.text = tableData[indexPath.row]
cell.lblPrice.text = tablePrice[indexPath.row]
if (tableAvailability[indexPath.row] == "NO") {
cell.imgCarName.image = UIImage(named: "nonselectable")
cell.lblPrice.textColor = UIColor(red: 172/255, green: 76/255, blue: 67/255, alpha: 1);
} else {
cell.imgCarName.image = UIImage(named: "deselected")
}
cell.selectionStyle = UITableViewCellSelectionStyle.None;
return cell
}
func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
let cell:TblCell = tableView.cellForRowAtIndexPath(indexPath) as TblCell
if (tableAvailability[indexPath.row] == "YES") {
println("Row \(indexPath.row) selected")
//var myBackView = UIView(frame: cell.frame)
cell.backgroundColor = UIColor(red: 190/255, green: 225/255, blue: 255/255, alpha: 1);
//cell.selectedBackgroundView = myBackView
cell.imgCarName.image = UIImage(named: "selected")
}
}
func tableView(tableView: UITableView!, didDeselectRowAtIndexPath indexPath: NSIndexPath!) {
let cell:TblCell = tableView.cellForRowAtIndexPath(indexPath) as TblCell
if (tableAvailability[indexPath.row] == "YES") {
println("Row \(indexPath.row) deselected")
//var myBackView = UIView(frame: cell.frame)
cell.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1);
//cell.selectedBackgroundView = myBackView
cell.imgCarName.image = UIImage(named: "deselected")
}
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 70
}
Any idea on how to fix this?
thanks in advance.
On 'didSelectRowAtIndexPath', you change the backgroundColor and imgCarName straight on the cell.
When you scroll, your cell gets reused! Meaning that the same cell is destroyed and used to present new content.
To keep track of what is selected, you need to save that state somewhere else than against the cell, maybe in your tableAvailability object, or any other object that handles the content of your cells.
I have close to 30 cells being occupied in my UITableView. I used storyboard mode to create the table. When I'm trying to call the cell that I selected its registering as 0 no matter what cell I've chosen. How do I get my cell to register the exact number I pushed and insert that into my currentTag?
Here is what I have so far
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return catNames.count;
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell
cell.textLabel?.text = catNames[indexPath.row]
cell.textLabel?.textColor = UIColor.whiteColor()
cell.backgroundColor = UIColor(red: 0x0e/255, green: 0x1b/255, blue: 0x35/255, alpha: 1.0)
cell.textLabel?.textAlignment = NSTextAlignment.Left
cell.textLabel?.lineBreakMode = NSLineBreakMode.ByTruncatingMiddle
cell.textLabel?.adjustsFontSizeToFitWidth = true
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
currentTag = tableView.tag
println("This is the \(currentTag)")
self.performSegueWithIdentifier("table2Segue", sender:self)
}
Use indexPath.row to find out which cell it is. If you have sections you will need to use indexPath.section as well.
NSIndexPath provides the section and row for the table view selection.
Similarly to how you set the cell's text via catNames[indexPath.row], you should use indexPath.row to determine the index of the cell that was tapped.
Therefore:
currentTag = indexPath.row;
// Doesn't work
cell.selectionStyle = .Blue
//Works when the selection is not multiple, if it's multiple with each selection the previous one disappear...
let cellBGView = UIView()
cellBGView.backgroundColor = UIColor(red: 0, green: 0, blue: 200, alpha: 0.4)
cell.selectedBackgroundView = cellBGView
Any answer how to set background color of the cells which are selected?
All the above answers are fine but a bit to complex to my liking. The simplest way to do it is to put some code in the cellForRowAtIndexPath. That way you never have to worry about changing the color when the cell is deselected.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
/* this is where the magic happens, create a UIView and set its
backgroundColor to what ever color you like then set the cell's
selectedBackgroundView to your created View */
let backgroundView = UIView()
backgroundView.backgroundColor = YOUR_COLOR_HERE
cell.selectedBackgroundView = backgroundView
return cell
}
This worked for me:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var selectedCell:UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
selectedCell.contentView.backgroundColor = UIColor.redColor()
}
// if tableView is set in attribute inspector with selection to multiple Selection it should work.
// Just set it back in deselect
override func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
var cellToDeSelect:UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
cellToDeSelect.contentView.backgroundColor = colorForCellUnselected
}
//colorForCellUnselected is just a var in my class
Swift 4.2
For multiple selections you need to set the UITableView property allowsMultipleSelection to true.
myTableView.allowsMultipleSelection = true
In case you subclassed the UITableViewCell, you override setSelected(_ selected: Bool, animated: Bool) method in your custom cell class.
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
if selected {
contentView.backgroundColor = UIColor.green
} else {
contentView.backgroundColor = UIColor.blue
}
}
Swift 3
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "yourCellIdentifier", for: indexPath)
cell.selectionStyle = .none
return cell
}
Swift 2
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "yourCellIdentifier", for: indexPath)
cell.selectionStyle = .None
return cell
}
The problem with Kersnowski's approach is that when the cell is redrawn the changes made when it's selected/deselected will be gone. So I would move the changes into the cell itself, which means subclassing is required here. For example:
class ICComplaintCategoryCell: UITableViewCell {
#IBOutlet var label_title: UILabel!
#IBOutlet var label_checkmark: UILabel!
override func layoutSubviews() {
super.layoutSubviews()
reload()
}
func reload() {
if isSelected {
contentView.backgroundColor = UIColor.red
}
else if isHighlighted{
contentView.backgroundColor = UIColor.red
}
else {
contentView.backgroundColor = UIColor.white
}
}
}
And in your table view delegate just call reload:
if let cell = self.table.cellForRowAtIndexPath(path) as? ICComplaintCategoryCell {
cell.reload()
}
Updated for Swift 3+, thanks #Bogy
You can also set cell's selectionStyle to.none in interface builder. The same solution as #AhmedLotfy provided, only from IB.
For Swift 3,4 and 5 you can do this in two ways.
1) class: UITableViewCell
override func awakeFromNib() {
super.awakeFromNib()
//Costumize cell
selectionStyle = .none
}
or
2) tableView cellForRowAt
cell.selectionStyle = .none
If you want to set selection color for specific cell, check this answer:
https://stackoverflow.com/a/56166325/7987502
UITableViewCell has an attribute multipleSelectionBackgroundView.
https://developer.apple.com/documentation/uikit/uitableviewcell/1623226-selectedbackgroundview
Just create an UIView define the .backgroundColor of your choice and assign it to your cells .multipleSelectionBackgroundView attribute.
Swift 3
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let selectedCell:UITableViewCell = tableView.cellForRow(at: indexPath)!
selectedCell.contentView.backgroundColor = UIColor.darkGray
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
let selectedCell:UITableViewCell = tableView.cellForRow(at: indexPath)!
selectedCell.contentView.backgroundColor = UIColor.clear
}
By adding a custom view with the background color of your own you can have a custom selection style in table view.
let customBGColorView = UIView()
customBGColorView.backgroundColor = UIColor(hexString: "#FFF900")
cellObj.selectedBackgroundView = customBGColorView
Add this 3 line code in cellForRowAt method of TableView.
I have used an extension in UIColor to add color with hexcode. Put this extension code at the end of any Class(Outside the class's body).
extension UIColor {
convenience init(hexString: String) {
let hex = hexString.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
var int = UInt32()
Scanner(string: hex).scanHexInt32(&int)
let a, r, g, b: UInt32
switch hex.characters.count {
case 3: // RGB (12-bit)
(a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
case 6: // RGB (24-bit)
(a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF)
case 8: // ARGB (32-bit)
(a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
default:
(a, r, g, b) = (255, 0, 0, 0)
}
self.init(red: CGFloat(r) / 255, green: CGFloat(g) / 255, blue: CGFloat(b) / 255, alpha: CGFloat(a) / 255)
}
}
SWIFT 3/4
Solution for CustomCell.selectionStyle = .none if you set some else style you saw "mixed" background color with gray or blue.
And don't forget! func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) didn't call when CustomCell.selectionStyle = .none.
extension MenuView: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cellType = menuItems[indexPath.row]
let selectedCell = tableView.cellForRow(at: indexPath)!
selectedCell.contentView.backgroundColor = cellType == .none ? .clear : AppDelegate.statusbar?.backgroundColor?.withAlphaComponent(0.15)
menuItemDidTap?(menuItems[indexPath.row])
UIView.animate(withDuration: 0.15) {
selectedCell.contentView.backgroundColor = .clear
}
}
}
Swift 5 - This works for me:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let selectedCell:UITableViewCell = tableView.cellForRow(at: indexPath as IndexPath)!
selectedCell.contentView.backgroundColor = .red
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
let cellToDeSelect:UITableViewCell = tableView.cellForRow(at: indexPath as IndexPath)!
cellToDeSelect.contentView.backgroundColor = .clear
}
You can use standard UITableViewDelegate methods
- (nullable NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
EntityTableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[cell selectMe];
return indexPath;
}
- (nullable NSIndexPath *)tableView:(UITableView *)tableView willDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
EntityTableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[cell deSelectMe];
return indexPath;
}
in my situation this works, cause we need to select cell, change color, and when user taps 2 times on the selected cell further navigation should be performed.
Swift 4
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
let selectedCell = tableView.cellForRow(at: indexPath)! as! LeftMenuCell
selectedCell.contentView.backgroundColor = UIColor.blue
}
If you want to unselect the previous cell, also you can use the different logic for this
var tempcheck = 9999
var lastrow = IndexPath()
var lastcolor = UIColor()
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
if tempcheck == 9999
{
tempcheck = 0
let selectedCell = tableView.cellForRow(at: indexPath)! as! HealthTipsCell
lastcolor = selectedCell.contentView.backgroundColor!
selectedCell.contentView.backgroundColor = UIColor.blue
lastrow = indexPath
}
else
{
let selectedCelllasttime = tableView.cellForRow(at: lastrow)! as! HealthTipsCell
selectedCelllasttime.contentView.backgroundColor = lastcolor
let selectedCell = tableView.cellForRow(at: indexPath)! as! HealthTipsCell
lastcolor = selectedCell.contentView.backgroundColor!
selectedCell.contentView.backgroundColor = UIColor.blue
lastrow = indexPath
}
}
I'm trying to do a simple UICollectionView with a custom cell composed of an UIImageView and an UIView above.
When a cell is not selected, the UIView on the top of the cell have is backgroundColor property set to UIColor(red: 1, green: 1, blue: 1, alpha: 0.5).
I have issues with the selection. The collectionView:didSelectItemAtIndexPath: method is called but when I change the UIView described previously, nothing happen.
Here is the code of my collectionView :
class TestCollectionViewController: UICollectionViewController
{
var items = [1, 2, 3]
let cellId = "Cell"
override func viewDidLoad()
{
self.collectionView.allowsMultipleSelection = true
self.collectionView.delaysContentTouches = false
}
override func collectionView(collectionView: UICollectionView!, numberOfItemsInSection section: Int) -> Int
{
return items.count
}
override func collectionView(collectionView: UICollectionView!, cellForItemAtIndexPath indexPath: NSIndexPath!) -> UICollectionViewCell!
{
var cell = collectionView.dequeueReusableCellWithReuseIdentifier(cellId,
forIndexPath: indexPath) as TestingCollectionViewCell
let item = items[indexPath.row]
cell.imageView.image = UIImage(named: "img")
cell.overlayView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 0.5)
return cell
}
override func collectionView(collectionView: UICollectionView!, didSelectItemAtIndexPath indexPath: NSIndexPath!)
{
var cell = collectionView.dequeueReusableCellWithReuseIdentifier(cellId,
forIndexPath: indexPath) as TestingCollectionViewCell
cell.overlayView.backgroundColor = UIColor.clearColor()
}
override func collectionView(collectionView: UICollectionView!, didDeselectItemAtIndexPath indexPath: NSIndexPath!)
{
var cell = collectionView.dequeueReusableCellWithReuseIdentifier(cellId,
forIndexPath: indexPath) as TestingCollectionViewCell
cell.overlayView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 0.5)
}
}
If this snippet is not enough, here is my project
You should not be dequeuing a new cell in didSelectItemAtIndexPath (or in didDeselect either) -- this is creating (or reusing) a new cell, not getting the one you selected. Use this instead,
var cell = collectionView.cellForItemAtIndexPath(indexPath)
To me the following code worked better (the code of rdelmar crashed sometimes, which might be a bug? in Swift):
(collectionView.cellForItemAtIndexPath(indexPath) as myCollectionViewCellType).uiBackground?.backgroundColor = UIColor.blackColor()
Edit: I forgot to mention: My collectionView-Items are based on their own class to which I cast. uiBackground is an element of that class
Swift 3.0
let cell = collectionView.cellForItem(at: indexPath)
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath)
{
//saving index path of the image loaded from imageproperty_array
selected_imagepath = imageproperty_array[indexPath.row] as String
//saving index of the selected cell item as Int
selected_imageindex = indexPath.row
}