I have a dark gray view background with a transparent tableview. I'm using the following code to try and stop cell highlight when a cell is clicked. It works except right when the cell is initially clicked, I see a highlight. I then transition to another scene after that. When I come back, the cell is not highlighted.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var selectedCell:UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
selectedCell.contentView.backgroundColor = UIColor.clearColor()
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
How do I disable the initial cell highlighting that is still going on?
Set UITableViewCell selection style none
cell.selectionStyle = .None
I found that the other answers did not work for me as they required a double click to select. This did work.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
UITableViewDelegate has methods to deal with cell highlights, probably
tableView(_:shouldHighlightRowAt:) is what you are looking for
Check the documentation for the other methods
The simplest way to prevent highlighting is setting selectionStyle to None. Here's how you can achieve this :
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
cell.selectionStyle = .None
return cell
}
Related
I am using a UITableView and what I am doing is I am changing the color of the cell when I tap on the cell using didSelectRow function of UITableView at cellForRowAt. The thing which is bothering me is when I scroll down or scroll up, those cells whom I changed the color before were changed to other cells. Here is my code:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = myTableView.dequeueReusableCell(withIdentifier: "TasksTableViewCell") as! TasksTableViewCell
cell.backView.backgroundColor = .white
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = myTableView.cellForRow(at: indexPath) as! TasksTableViewCell
cell.backView.backgroundColor = UIColor(named: "primaryViewColor")
}
Does anyone knows why this happens? Does anyone has a solution that when only those cells changes color whom I tap on, and when I scroll down or move up only those cells have the other color?
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)
}
I encountered do you see the problem many times. Even if using and iVar can solve the problem, You are mixing "Controller" logic and "Model" logic.
I usually prefer to move "selection" state inside the model.
Suppose You have a class "Contact" you use to fill cell data (usual MVC pattern)
I add:
class contact{
..
var selected = false
}
AND in TV delegation method I use to apply selection, OR better I use a custom selection method in a custom cell (for example to see a √ element in cell)
As a bonus multiple selection come for free, and you can also save current selections for next run :)
So as I understand you select a cell and after that other cells look like they are selected?
If so I think this is happening because you change the background color of the cell and tableViews and collectionViews are reusing the cells, basically keeping the background you changed behind.
TableViewCells are reused as soon as they leave the visible area.
This means that a cell whose background you have colored will be deleted from the view hierarchy as soon as it is scrolled up or down. If the corresponding row is scrolled in again, the function cellForRowAt is called again for this IndexPath and the cell gets a white background.
The easiest is to save the IndexPaths of the selected cells and check in the cellForRowAt function if the current cell has to be selected.
Add the following var to the viewController class:
var selectedIndexPaths = Set<IndexPath>()
and modify the tableView delegate methods:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = myTableView.dequeueReusableCell(withIdentifier: "TasksTableViewCell") as! TasksTableViewCell
cell.backView.backgroundColor = (selectedIndexPaths.contains(indexPath) ? UIColor(named: "primaryViewColor") : .white)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
if selectedIndexPaths.contains(indexPath)
{
selectedIndexPaths.remove(indexPath)
}
else
{
selectedIndexPaths.insert(indexPath)
}
tableView.reloadRows(at: [indexPath], with: .none)
}
You can use
step 1: create model
class DemoModel {
var isSelected: Bool = false
var color: UIColor = .While
}
step 2: and in tableview
var listDemo: [DemoModel] = [DemoModel(),...]
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = myTableView.dequeueReusableCell(withIdentifier:
"TasksTableViewCell") as! TasksTableViewCell
var obj = listDemo[indexPath.row]
cell.backView.backgroundColor = obj.color
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
var obj = listDemo[indexPath.row]
obj.color = UIColor(named: "primaryViewColor")
tableView.reloadRows(at: [indexPath], with: .automatic)
}
How to disable highlight on tableview without disable the func? i tried these and now i can't go to the another page.
func tableView(tableView: UITableView, shouldHighlightRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return false
}
Set the selectionStyle property of your UITableViewCell to .None.
This will permit selection but prevent the default highlighting behavior.
In the cellForRowAtIndexPath implementation in your controller, set the selectionStyle to .None as below:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
cell.selectionStyle = .None
// ...
return cell
}
Step 1: Select your Tableview Cell
Step 2: After then go to Tableview Cell Properties and Set your
Tableview Cell Selection ".None"
Or you can also Do Programmatically add "Tablecell.selectionStyle = .none
" this code in your cellForRowAtIndexPath method.
I believe disabling selection should do the trick.
tableView.allowsSelection = false
Or, if you want the user to be able to temporarily tap the table you could do this:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
//your code
tableView.deselectRowAtIndexPath(indexPath)
}
When I tap on the cells of my table view, they darken to a grey color, and don't turn back to white until I tap on a different cell. Is there some sort of Boolean I have to set for it to not do that?
Here's a screenshot explaining my problem:
Links to other websites would be helpful, if it would mean a more detailed description. (Unless it's a super simple fix, then the right code or steps-to-take would be easier than a link.)
This is the default behaviour of UITableView.
You must call deselectRowAtIndexPath inside of didSelectRowAtIndexPath inside your UITableViewController class.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
Check out the iOS Documentation for more information.
UITableView
UITableViewDelegate
Swift 3
Option 1: (Which I always use)
To give it fade out animation after selected with gray you can do this:
func tableView(_ tableView: UITableView,
didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}
Option 2:
To remove the highlight effect completely you can add this line to your cellForRowAt :
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = .....
cell.selectionStyle = .none
return cell
}
You can do this a couple ways...
tableView.allowsSelection = false
You can set the tableView in xCode Storyboard to not have any selection under the fourth tab.
Or, you can do this on the cell cell.selectionStyle = UITableViewCellSelectionStyle.None
What you want is ultimately going to be about what behavior you are going after. Just do a little experimenting.
Swift 3
In a custom cell add this:
override func awakeFromNib() {
super.awakeFromNib()
selectionStyle = .none
}
This ensures you won't even see the gray when the cell is tapped. This code in the UITableViewDelegate only deselects when tapped.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}
Just Simply click on the cell and go to attributes inspector you will find Selection Style , select none.
You can change style by:
[cell setSelectionStyle:UITableViewCellSelectionStyleGray];
Swift 4.1
tableView.deselectRow(at: indexPath, animated: true)
In the storyboard or xib,
In the Tableview cell,
you can select selection to "none",
in the atributes inspector
I am trying to remove the highlight when selecting a table view cell, but want to keep the checkmark that appears.
When I try this in cellForRowAtIndexPath:
cell.backgroundView = UIView()
cell.backgroundView?.backgroundColor = UIColor.clearColor()
It only removes the highlight underneath the checkmark, rather than the whole row (refer to image attached).
When I try this in cellForRowAtIndexPath:
cell.selectionStyle = UITableViewCellSelectionStyle.None
It no longer displays the checkmark.
UPDATE: tried this, does the same thing as cell.selectionStyle where it no longer does checkmark
func tableView(tableView: UITableView, shouldHighlightRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return false
}
What is a good way of doing this? I want it to still function like a checkbox but just don't want the blue highlighting to occur. TableView is dynamically generated:
checkBoxView = UITableView()
checkBoxView.frame = CGRect(x: qView.bounds.midX, y: qView.bounds.midY, width: qView.bounds.width - 100, height: qView.bounds.height/1.5)
checkBoxView.center = CGPointMake(qView.bounds.midX, qView.bounds.midY)
checkBoxView.delegate = self
checkBoxView.dataSource = self
checkBoxView.tag = 100
checkBoxView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
checkBoxView.setEditing(true, animated: true)
self.qView.addSubview(checkBoxView)
Table View Functions:
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.checkBoxContent.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:UITableViewCell = checkBoxView.dequeueReusableCellWithIdentifier("cell") as! UITableViewCell
cell.textLabel?.text = self.checkBoxContent[indexPath.row]
cell.backgroundColor = UIColor.clearColor()
cell.tintColor = UIColor.greenColor()
return cell
}
func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle {
return UITableViewCellEditingStyle(rawValue: 3)!
}
In order to keep the checkmark, you can't set false to this shouldHighlightRowAtIndexPath method. If you do so, this wouldn't even show the checkmark on the left hand side at all.
What i have done is changing the "selectedBackgroundView" of cell which would keep the left-hand side checkmark and giving me the chance to set the background color. I enclose some code here and hope it would help.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(cellID, forIndexPath: indexPath) as! RecordTableViewCell
cell.selectedBackgroundView = UIView(frame: cell.frame)
cell.selectedBackgroundView?.backgroundColor = UIColor.orangeColor()
return cell
}
None of the suggestions above worked for me. In Swift 5, add this line to your cellForRowAtIndexPath function:
cell.selectionStyle = UITableViewCell.SelectionStyle.none
Swift 1.2 use:
tableView.deselectRowAtIndexPath(indexPath, animated: true)
In the didSelectRowAtIndexPath delegate method.
Theres an official way to do this with a UITableView, which is to use this :
optional func tableView(_ tableView: UITableView, shouldHighlightRowAtIndexPath indexPath: NSIndexPath) -> Bool
If you return YES for this method, then the tableview will highlight a cell when it is clicked.
Also note if you dont want to use that, that you need to change the contentView.backgroundColor, rather than just the cell backgroundColor. But the highlighting route is the best one to go down.
Documentation here : https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableViewDelegate_Protocol/index.html#//apple_ref/occ/intfm/UITableViewDelegate/tableView:shouldHighlightRowAtIndexPath:
I have a custom UITableViewCell containing a UIActivityIndicatorView (spinner), and I try to click on the cell so that spinner starting to animate. So I try to implement following in UITableViewController:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.dequeueReusableCellWithIdentifier("testcase", forIndexPath: indexPath) as TestCaseTableViewCell
cell.spinner.startAnimating()
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
I have the instance variable "spinner" in my TestCaseTableViewCell(custom cell class):
#IBOutlet weak var spinner: UIActivityIndicatorView!
But it didn't work......
I just want to click on the cell, and the spinner starts to animate cause I want to do something in this period. While the something is done, I can show something like "OK" in the cell(as the same position of the spinner). How can I achieve that?
The problem is with how you are retrieving your cell from the table view: dequeueReusableCellWithIdentifier(identifier: String, forIndexPath indexPath: NSIndexPath). This method asks the UITableView for a cell from its reuse cache when you need a new cell to display, so should only be used in the tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) method of your table view's data source.
To ask the table view for an on-screen cell, use cellForRowAtIndexPath(indexPath: NSIndexPath). Your code sample then becomes:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if let cell = tableView.cellForRowAtIndexPath(indexPath) as? TestCaseTableViewCell {
cell.spinner.startAnimating()
}
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
Another simple method:
Select your UIActivityIndicatorView and check "Animating" in the attribute inspector
Check "hidden"
Now do this:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.dequeueReusableCellWithIdentifier("testcase", forIndexPath: indexPath) as TestCaseTableViewCell
cell.spinner.hidden = false // <== Here
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
Don't forget to hide the unhidden UIActivityIndicatorView if needed ;)