I am trying to figure out how to programmatically(not in storyboard) set the colour for UITableViewCellAccessoryType.Checkmark.
I feel kinda stupid asking how to do something as simple as this, but I could not find the answer in the apple docs. Any help would be great. Thanks.
I set the accessory type like this:(works fine)
cell.accessoryType = .Checkmark
EDIT : If you want to change the image used for checkmark, this worked for me. But POB's answer is what I ended up using to simply change the colour.
let checkImage = UIImage(named: "checkmark.png")
let checkmark = UIImageView(image: checkImage)
cell.accessoryView = checkmark
The following code should work:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
//Change cell's tint color
cell.tintColor = UIColor.redColor()
//Set UITableViewCellAccessoryType.Checkmark here if necessary
cell.accessoryType = .Checkmark
/* ... */
return cell
}
Here is code for Swift 3.0
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.tintColor = UIColor.red
cell.accessoryType = .checkmark
return cell
}
You can also do it globally (for all table view cells) like this:
UITableViewCell.appearance().tintColor = .green
Nice little trick :)
Related
I have a tableview in my storyboard where the prototype cell has a disclosure indicator by default.
When I populate my table I want to remove the indicator only from the last cell AND center a spinner on it.
I'm doing it like this:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CharacterCell", for: indexPath) as! CharacterCell
if indexPath.row == charactersViewModel.charactersCount - 1 {
cell.accessoryType = .none
cell.accessoryView = .none
// Spinner
let spinner = UIActivityIndicatorView(style: .large)
spinner.color = .white
spinner.center = cell.contentView.center
cell.contentView.addSubview(spinner)
spinner.startAnimating()
}
return cell
}
The problem is that the spinner is offcenter, a little bit to the left, just like if the accessory is still there, but hidden.
I feel maybe I'm missing the lifecycle of a table cell, maybe it's getting the center value of the content view when the accessory is still there, so when it's removed it is offcenter?
I tried on willDisplay as well but the same thing happens.
Any tips on this?
As #Paulw11 mentioned, I used a second subclass and created another cell prototype in my tableview.
Then when the last position at the table is reached, we can use the second prototype on cellForRowAt.
Here how it is:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row >= charactersViewModel.charactersCount - 1 {
reloadRows(indexPath: indexPath)
let cell = tableView.dequeueReusableCell(withIdentifier: "LoadingCharacterCell", for: indexPath) as! LoadingCharacterCell
cell.startSpinner()
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "CharacterCell", for: indexPath) as! CharacterCell
cell.configureCell(charactersViewModel: charactersViewModel, cell: cell, index: indexPath.row)
return cell
}
}
private func reloadRows(indexPath: IndexPath) {
var indexPathList = [IndexPath]()
indexPathList.append(indexPath)
charactersTableView.reloadRows(at: indexPathList, with: .automatic)
}
And with the reloadRows function, the last cell is updated and removed when the table receives more data.
This question already has answers here:
How can I disable the UITableView selection?
(42 answers)
Closed 4 years ago.
I would like to make the cells of a tableView non-selectable but still allow scrolling. When I placed
tableView.isUserInteractionEnabled = false
which is recommended in some answers in viewDidLoad, it prevents selection but also prevents scrolling.
Adding:
cell.selectionStyle = .none
in cellforrowatindexpath as below not have any effect for me.
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
self.tableView.beginUpdates()
self.tableView.endUpdates()
if let cell = tableView.dequeueReusableCell(withIdentifier: "myMessageCell", for: indexPath) as? myMessageCell {
cell.message = messages[indexPath.row]
cell.selectionStyle = .none
}
return tableView.dequeueReusableCell(withIdentifier: "myMessageCell", for: indexPath)
}
Can anyone suggest how to prevent selection without preventing scrolling?
Thanks in advance for any suggestions.
Hope you are looking for this one:
tableView.allowsSelection = false
The problem is you are not returning the same cell that you are dequeuing. Instead you are dequeuing another cell and returning it which has none of the properties that you have set.
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: "myMessageCell", for: indexPath) as? myMessageCell {
cell.message = messages[indexPath.row]
cell.selectionStyle = .none
return cell // Return the cell here instead
}
// return tableView.dequeueReusableCell(withIdentifier: "myMessageCell", for: indexPath) // Return another cell which has none of your properties set.
return UITableViewCell() // return default cell in case your cell is not dequeued
}
I am trying to make a custom table view cell.
If I do this:
class TableViewCell: UITableViewCell {
#IBOutlet weak var cellBackgroundImage : UIImageView!
}
And:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! TableViewCell
cell.cellBackgroundImage.backgroundColor = UIColor.white
cell.cellBackgroundImage.layer.masksToBounds = false
cell.cellBackgroundImage.layer.cornerRadius = 5
let event = self.fetchedResultsController.object(at: indexPath)
self.configureCell(cell, withEvent: event)
return cell
}
I obtain a white rounded cell background. Easy. And I can use the original cell.textLabel.text.
Perfect.
But, if I want to do something more complex:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as? TableViewCell
if (cell == nil) {
cell = UITableViewCell(style: UITableViewCellStyle.subtitle, reuseIdentifier: "Cell") as? TableViewCell
cell?.cellBackgroundImage.backgroundColor = UIColor.white
cell?.cellBackgroundImage.layer.masksToBounds = false
cell?.cellBackgroundImage.layer.cornerRadius = 5
self.configureCell(cell!, withObject: object)
}
And at the same time to use the original table view properties as UITableViewCellStyle.subtitle and cell.accessoryView, the app crashes or shows the wrong output.
THIS MEANS THAT I MUST USE A FULL CUSTOM CELL WITH MORE OUTLETS TO REPLACE THE ORIGINAL ELEMENTS AS UITableViewCellStyle.subtitle and cell.accessoryView ???
I will express it in a different way:
Can I use a custom tableview cell only for one purpose (like the rounded background) and use the original elements such as the subtitle style and the accesory view?
In afirmative case, how?
I have multiple UICollectionViewCells. When the user taps on a specific cell, I would like my app to change the background image of the touched cell.
My approach is to focus on the didSelectItemAtIndexPath method. When a cell is touched, this method will be called.
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
var cell: UICollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier("cellIdentifier", forIndexPath: indexPath) as! UICollectionViewCell
cell.backgroundView = UIImageView(image: UIImage(named: "myImage"))
}
However, I can't get it working but I don't know why. The issue is probably related to indexPath, that doesn't return a correct value of the cell. I tried using indexPath.row and this does actually return an Int number of the cell.
What's more, I'm also creating a new UICollectionViewCell with var but this cell already exists.
Why isn't the cell updating its background image? How do I change the background image of a UICollectionViewCell that has been touched by the user?
I totally agree with the Josh's answer, but if you change the background image using the didSelectItemAtIndexPath method it works fine as well. Then, you can use the cellForRowAtIndexPath method that returns the UITableViewCell at the specified indexPath, like in the following way:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var cell = tableView.cellForRowAtIndexPath(indexPath) as UITableViewCell!
cell.backgroundView = UIImageView(image: UIImage(named: "photo2"))
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! UITableViewCell
cell.backgroundView = UIImageView(image: UIImage(named: "photo1"))
cell.selectionStyle = .None
return cell
}
I just put the selectionStyle to .None to avoid the highlight. I hope this help you.
I have a regular UITableView with single selection enabled. My problem is that if the user selects multiple rows then the original rows remain selected. I also have a problem where the highlight remains gray no matter if I set the cell.selectionStyle = UITableViewCellSelectionStyle.Blue
My view controller is defined in the Storyboard.
Table View
Content: Dynamic Prototypes
Selection: Single Selection
Show Selection on Touch [X]
Background: Black Color
Index Row Limit: 0
Table Cell View
Style: Custom
Selection: Blue
Background: Black Color
Here are some screenshots:
Here is my code:
class AreaViewController: UITableViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
self.tableView.backgroundColor = backgroundColour
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCellWithIdentifier("areacell", forIndexPath: indexPath) as! UITableViewCell
cell.selectionStyle = UITableViewCellSelectionStyle.Blue
cell.textLabel?.text = "Cell Contents"
cell.textLabel?.textColor = UIColor.whiteColor()
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
let cell = tableView.dequeueReusableCellWithIdentifier("areacell", forIndexPath: indexPath) as! UITableViewCell
}
}
I must be missing something obvious but I've not been able to see anything non standard.
From the UITableViewCell Class Reference
UITableViewCellSelectionStyleBlue The cell has a default background
color when selected.
In iOS 7, the selection color is no longer blue. Use
UITableViewCellSelectionStyleDefault instead.
If you want a special background color for selected cells you have to set the cells' backgroundView:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath) as! UITableViewCell
// Configure the cell...
let backgroundView = UIView()
backgroundView.backgroundColor = UIColor.redColor()
cell.selectedBackgroundView = backgroundView
return cell
}
Looks like this:
Argh! I found it at last. Seems like I was calling let cell = tableView.dequeueReusableCellWithIdentifier("areacell", forIndexPath: indexPath) as! UITableViewCell in the didSelectRowAtIndexPath method. Removing it caused everything to start working again. Obvious really. Thanks for your help zisoft in putting me on the right road.