Programmatically highlighting UITableViewCell in Swift - ios

How do I programmatically highlight a table view cell?
I am using:
tableView.selectRow(at: indexPath, animated: true, scrollPosition: .none)
tableView.delegate?.tableView!(self.ordersTableView, didSelectRowAt: indexPath)
The problem I am having is that the cell IS being selected (all the actions specified in my didSelectRowAt are being performed) but the cell does now highlight. It doesn't appear selected.
What I am trying to achieve is like the Settings app on the iPad. You launch the app and see the "general" cell already selected and highlighted.
The cells highlight properly when touched by the user.
I have even tried overwriting the isSelected variable in my subclass of UITableViewCell.
Ok turns out it was a problem with background tasks. The cells were loaded again after I selected them and that's why the selection wasn't visible.

Note: Your question title says, you have a query with cell highlight and your question description says, you have a problem with cell selection. Both are different events.
Here is an answer, how you can manage (set color) on tableview row (cell) selection:
// make sure your tableview row selection is enabled
yourTableViewInstance.allowsSelection = true
// handle highlighted background in data source method also
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "textview") as! YourTableViewCell
cell.contentView.backgroundColor = cell.isSelected ? UIColor.red : UIColor.gray
return cell
}
// didSelectRowAtIndexPath - change background color
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) as? YourTableViewCell {
cell.contentView.backgroundColor = UIColor.red
}
}
// didDeselectRowAtIndexPath - change background color
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) as? YourTableViewCell {
cell.contentView.backgroundColor = UIColor.gray
}
}

Try this:-
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
var selectedCell:UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
selectedCell.contentView.backgroundColor = UIColor.redColor()
}

Here is another option to handle cell background selection
class YourTableViewCell: UITableViewCell {
// override cell selection
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
if self.selectedBackgroundView == nil {
let bgView = UIView()
self.selectedBackgroundView = bgView
}
self.selectedBackgroundView?.backgroundColor = selected ? UIColor.red : UIColor.gray
}
}
// enable row/cell selection
yourTableViewInstance.allowsSelection = true
// handle highlighted background in data source method also
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "textview") as! YourTableViewCell
if self.selectedBackgroundView == nil {
let bgView = UIView()
self.selectedBackgroundView = bgView
}
self.selectedBackgroundView?.backgroundColor = selected ? UIColor.red : UIColor.gray
return cell
}

Related

TextLabel colour automatically changed when i Scroll UiTableView

I changing textlabel color on didSelectRowAt but when I scroll UITableView it also effects in other textlabel also
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath) as! TableViewCell
if (cell.LBLIntrest.textColor == (UIColor.black))
{
cell.LBLIntrest.textColor = Uicolor.blue
} else {
cell.LBLIntrest.textColor = Uicolor.black
}
}
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.
This should work for you.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath) as! TableViewCell
setSelectedColor(cell: cell)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
...
...
if let selectedRows = tableView.indexPathsForSelectedRows, selectedRows.contains(indexPath) {
setSelectedColor(cell: cell)
}
return cell
}
func setSelectedColor(cell: UITableViewCell) {
if (cell.LBLIntrest.textColor == (UIColor.black)) {
cell.LBLIntrest.textColor = Uicolor.blue
} else {
cell.LBLIntrest.textColor = Uicolor.black
}
}
But, I would recommend moving that cell.LBLIntrest.textColor = Uicolor.blue to UITableViewCell under func setSelected(_ selected: Bool, animated: Bool) method
class TableViewCell: UITableViewCell {
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// label textColor logic goes here
// make use of selected
}
}

UITableView : Strange checkmark accessory type behavior

A gif to introduce my problem :
In my UITableView I set a checkmark accessory type but a white background appears instead of displaying the checkmark of the cell. The checkmark is here, but why do I have this white background ?
The tint color of my cell is set to white, changing it just change the color of the checkmark and the background is still here.
My code :
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) as? CheckTableViewCell {
if cell.titleLabel.text != "" {
cell.accessoryType = .checkmark
}
}
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
tableView.cellForRow(at: indexPath)?.accessoryType = .none
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? CheckTableViewCell {
cell.setUp(withTitle: dataSource[indexPath.row].title)
return cell
}
return CheckTableViewCell()
}
func setUp(withTitle title : String){
self.titleLabel.text = title
}
Any idea ?
I had to set both cell content's View and UITableView background color to pink in StoryBoard to make it works.

Setting TableViewCell Label colour on row selection Swift 3

I have a TableView, and the table is populated from an array. The cell is of type TableViewCell.xib. I want to change the colour of the label in the cell.
Here's my TableViewController
struct cell_data {
let label1: String!
}
class TableViewController: UITableViewController {
let cellDataArray = [cell_data]([cell_data(label1: "This text is for label 1")])
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return cellDataArray.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = Bundle.main.loadNibNamed("TableViewCell", owner: self, options: nil)?.first as! TableViewCell
cell.label_1.text = cellDataArray[indexPath.row].label1
cell.selectionStyle = .none
let whiteRoundedView : UIView = UIView(frame: CGRect(x:10, y:5, width: self.view.frame.size.width - 20, height: cell.frame.size.height - 7))
whiteRoundedView.layer.backgroundColor = UIColor.green.cgColor
whiteRoundedView.layer.masksToBounds = false
whiteRoundedView.layer.shadowOffset = CGSize(width: -1, height: 1)
whiteRoundedView.layer.shadowOpacity = 0.3
cell.contentView.addSubview(whiteRoundedView)
cell.contentView.sendSubview(toBack: whiteRoundedView)
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
}
override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
}
}
What I want to do be able to do is change the colour of the label of the cell when I select a row without affecting the UIView inside the cell. That is, once I change the height of the UIView when I select a row, I have tried reloading but reloading the cell set the UIView's height to the original setting.
And once I have set the label's colour, I want to set it back to it's original colour when I deselect the row.
I hope I made it clear enough. Thanks in advance.
You don't need to reloading the cell to update the label's color. You can try by overriding method in your TableViewCell with the following code:
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
if (selected) {
//Change your label color for selected state
} else {
//Change your label color for unselected state
}
}
try this:
func tableView(tableView: UITableView, didHighlightRowAtIndexPath indexPath: NSIndexPath)
{
let cell = tableView.cellForRowAtIndexPath(indexPath)! as! customTableViewCell // name of your custom cell class
cell.label_1.backgroundColor = UIColor.whiteColor()//give your selection color
}
Try this
override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath) as yourCell
cell.yourlable.textcolor = yourColor;
}

Highlight TableView Cell's TextLabel text colour

I am using a popover tableview in my project. I want to change the tableview cell's text colour from grey to red on selection. And i also want the highlighted color to remain red when the popover tableview is loaded next time like left menu selection. Need help to do this. I have provided the code for the popover tableview.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if tableView === tableViewPopOver {
let cell = UITableViewCell(style: .Default, reuseIdentifier: nil)
cell.textLabel?.text = FeedFilter.allValues[indexPath.row].rawValue
if indexSelected == indexPath.row {
cell.textLabel?.textColor = UIColor.redColor()
} else {
cell.textLabel?.textColor = UIColor.lightGrayColor()
}
//cell.selectionStyle = .None
return cell
}
let cell = tableView.dequeueReusableCellWithIdentifier(kDreamFeedTableViewCell, forIndexPath: indexPath) as! DreamFeedTableViewCell
cell.selectionStyle = .None
let dream = self.arrayDreams[indexPath.row]
cell.dream = dream
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if tableView === tableViewPopOver {
//tableViewPopOver?.cellForRowAtIndexPath(indexPath)?.textLabel?.highlightedTextColor = UIColor.redColor()
//selectedIndexPath = indexPath.row
let cell = tableView.cellForRowAtIndexPath(NSIndexPath.init(forRow: indexSelected, inSection: 0))
cell?.textLabel?.textColor = UIColor.lightGrayColor()
let cell2 = tableView.cellForRowAtIndexPath(indexPath)
cell2?.textLabel?.textColor = UIColor.redColor()
tableView.deselectRowAtIndexPath(indexPath, animated: true)
indexSelected = indexPath.row
self.popover.dismiss()
NRLoader.showLoader()
self.searchDreams(true)
}
else { // dream feed tableview
tableView .deselectRowAtIndexPath(indexPath, animated: false)
let dream = self.arrayDreams[indexPath.row]
if !isValidUser(dream.user) {
return
}
if isCurrentUser(dream.user)
{
self.pushToUserDreamViewControllerForDream(dream)
}
else
{
tableView .deselectRowAtIndexPath(indexPath, animated: false)
self.pushToFeedDetailViewControllerForDream(dream)
}
}
}
I see a problem with your code relate to tableViewPopOver. If you set selection style is .None. You can't select cell.
With your problem I can suggest for you two way to resolve:
If you want use cell.textLabel?.highlightedTextColor you will have face a problem: background of cell will be grey or blue depend on style selection you select. If you can accept it. You can implement like this:
You create a variable to hold a cell selected. Maybe it is int value like var indexSelected = 3. And when you implement cellForRowAtIndexPath you should implement like this:
cell.textLabel?.text = FeedFilter.allValues[indexPath.row].rawValue
cell.textLabel?.highlightedTextColor = UIColor.redColor()
if indexPath.row == indexSelected {
tableView.selectRowAtIndexPath(indexPath, animated:true, scrollPosition: .None)
}
return cell
And in didSelectRowAtIndexPath you update indexSelected:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
indexSelected = indexPath.row //update selected row
}
If you don't want cell background change color. You can choose this way. You should create variable like the way above. But in cellForRowAtIndexPath you should implement:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell")//init cell it depend on your way create cell
cell?.textLabel?.text = "Your text"
if indexSelected == indexPath.row {
cell?.textLabel?.textColor = UIColor.redColor()
} else {
cell?.textLabel?.textColor = UIColor.lightGrayColor()
}
return cell!
}
and in didSelectCellAtIndexPath you should implement:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.cellForRowAtIndexPath(NSIndexPath.init(forRow: indexSelected, inSection: 0))
cell?.textLabel?.textColor = UIColor.lightGrayColor()
let cell2 = tableView.cellForRowAtIndexPath(indexPath)
cell2?.textLabel?.textColor = UIColor.redColor()
tableView.deselectRowAtIndexPath(indexPath, animated: true)
indexSelected = indexPath.row //update selected row
}
Here Demo: Demo
Hope this help!
To change cell's text colour to red on selection you need to implement didSelectRowAtIndexPath and change the cell text Color to red, but it will not stay red when you open it the next time. to handle that you need to have a member variable selectedIndexPath. So it will be something like this
var selectedIndexPath:NSIndexPath!
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if let cell = tableView.cellForRowAtIndexPath(indexPath) {
cell.textLabel?.highlightedTextColor = UIColor.redColor()
selectedIndexPath = indexPath
}
}
func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
if let cell = tableView.cellForRowAtIndexPath(indexPath) {
cell.textLabel?.highlightedTextColor = UIColor.grayColor()
selectedIndexPath = nil
}
}
And to load the table next time with the selected cell red text colour you need to add this line in your cellForRowAtIndexPath
Cell
cell.textLabel?.highlightedTextColor = indexPath == selectedIndexPath ? UIColor.redColor() : UIColor.grayColor()
}

Swift. Change Color of Custom Tableview Cell Label when selected

I have a Custom Tableview cell in swift and in that cell a label.
I want to be able to change the label when you select a cell.
How can I reference my custom UITableviewCell label in didSelectRowAtIndexPath
In Objective C to reference my custom cell in didSelectRowAtIndexPath I would use the following:
MPSurveyTableViewCell *cell = (MPSurveyTableViewCell *)[tableViewcellForRowAtIndexPath:indexPath];
cell.customLabel.TextColor = [UIColor redColor];
What must I do in swift to achieve the same result?
You just need to translate the same code to Swift.
var myCell = tableView.cellForRowAtIndexPath(indexPath) as! MPSurveyTableViewCell
myCell.customLabel.textColor = UIColor.redColor()
The Above Answers Are Incomplete
Because a UITableView reuses cells you need to check if the cells are selected and adjust the color appropriately in cellForRowAtIndexPath. There may be typos, but this is the complete answer:
func tableView(tableView: UICollectionView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cellIdentifierHere", forIndexPath: indexPath) as! MPSurveyTableViewCell
// setup your cell normally
// then adjust the color for cells since they will be reused
if cell.selected {
cell.customLabel.textColor = UIColor.redColor()
} else {
// change color back to whatever it was
cell.customLabel.textColor = UIColor.blackColor()
}
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath){
let cell = tableView.cellForRowAtIndexPath(indexPath) as! MPSurveyTableViewCell
cell.customLabel.textColor = UIColor.redColor()
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.None)
}
func tableView(tableView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.cellForRowAtIndexPath(indexPath) as! MPSurveyTableViewCell
// change color back to whatever it was
cell.customLabel.textColor = UIColor.blackColor()
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.None)
}
swift 3 xcode 8
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let Cell = tableView.cellForRow(at: indexPath)
Cell?.textLabel?.textColor = UIColor.red // for text color
Cell?.backgroundColor = UIColor.red // for cell background color
}
why not use setSelected in UITableViewCell subclass?
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
customLabel.textColor = selected ? UIColor.red : UIColor.black
}
or if you want it to go back to deselected color after a specific amount of time:
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
if selected {
customLabel.textColor = UIColor.red
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.2, execute: { [weak self] in
self?.customLabel.textColor = UIColor.black
}
}
}
Then just set your cell selectionStyle = .none
Try this,
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
var Cell = tableView.cellForRowAtIndexPath(indexPath) as! MPSurveyTableViewCell
Cell. customLabel.textColor = UIColor. redColor()
}
let CellObject = tableView.dequeueReusableCell(withIdentifier: "your cell identifier name") as! MPSurveyTableViewCell
CellObject.customLabel.textColor = UIColor.red

Resources