ios - uitableviewcell - How can I disable the UITableView selection?




uitableviewcell selection color swift (20)

When you tap a row in a UITableView, the row is highlighted and selected. Is it possible to disable this so tapping a row does nothing?


Objective-C:

  1. Below snippet disable highlighting but it also disable the call to didSelectRowAtIndexPath. So if you are not implementing didSelectRowAtIndexPath then use below method. This should be added when you are creating the table. This will work on buttons and UITextField inside the cell though.

    self.tableView.allowsSelection = NO;
    
  2. Below snippet disable highlighting and it doesn't disable the call to didSelectRowAtIndexPath. Set the selection style of cell to None in cellForRowAtIndexPath

    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    
  3. Below snippet disable everything on the cell. This will disable the interaction to buttons, textfields:

    self.tableView.userInteractionEnabled = false;
    

Swift:

Below are the Swift equivalent of above Objective-C solutions:

  1. Replacement of First Solution

    self.tableView.allowsSelection = false
    
  2. Replacement of Second Solution

    cell?.selectionStyle = UITableViewCellSelectionStyle.None
    
  3. Replacement of Third Solution

    self.tableView.userInteractionEnabled = false
    

FIXED SOLUTION FOR SWIFT 3

cell.selectionStyle = .none

All you have to do is set the selection style on the UITableViewCell instance using either:

Objective-C:

cell.selectionStyle = UITableViewCellSelectionStyleNone;

or

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

Swift 2:

cell.selectionStyle = UITableViewCellSelectionStyle.None

Swift 3 and 4.x:

cell.selectionStyle = .none

Further, make sure you either don't implement -tableView:didSelectRowAtIndexPath: in your table view delegate or explicitly exclude the cells you want to have no action if you do implement it.

More info here and here


As of iOS 6.0, UITableViewDelegate has tableView:shouldHighlightRowAtIndexPath:. (Read about it in the iOS Documentation.)

This method lets you mark specific rows as unhighlightable (and implicitly, unselectable) without having to change a cell's selection style, messing with the cell's event handling with userInteractionEnabled = NO, or any other techniques documented here.


For me, the following worked fine:

tableView.allowsSelection = NO;

This means didSelectRowAt# simply won't work. That is to say, touching a row of the table, as such, will do absolutely nothing. (And hence, obviously, there will never be a selected-animation.)

(Note that if, on the cells, you have UIButton or any other controls, of course those controls will still work. Any controls you happen to have on the table cell, are totally unrelated to UITableView's ability to allow you to "select a row" using didSelectRowAt#.)


From the UITableViewDelegate Protocol you can use the method willSelectRowAtIndexPath and return nil if you don't want the row selected.

In the same way the you can use the willDeselectRowAtIndexPath method and return nil if you don't want the row to deselect.


I've been battling with this quite profusely too, having a control in my UITableViewCell prohibited the use of userInteractionEnabled property. I have a 3 cell static table for settings, 2 with dates, 1 with an on/off switch. After playing about in Storyboard/IB i've managed to make the bottom one non-selectable, but when you tap it the selection from one of the top rows disappears. Here is a WIP image of my settings UITableView:

If you tap the 3rd row nothing at all happens, the selection will stay on the second row. The functionality is practically a copy of Apple's Calendar app's add event time selection screen.

The code is surprisingly compatible, all the way down to IOS2 =/:

- (NSIndexPath *)tableView: (UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.row == 2) {
        return nil;
    }
    return indexPath;
}

This works in conjunction with setting the selection style to none, so the cell doesn't flicker on touch down events


If you want selection to only flash, not remain in the selected state, you can call, in

didSelectRowAtIndexPath

the following

[tableView deselectRowAtIndexPath:indexPath animated:YES];

so it will flash the selected state and revert.


In your UITableViewCell's XIB in Attribute Inspector set value of Selection to None.


This is what I use :

cell.selectionStyle = UITableViewCellSelectionStyleNone;

in cellForRowAtIndexPath write this code.


To sum up what I believe are the correct answers based on my own experience in implementing this:

If you want to disable selection for just some of the cells, use:

cell.userInteractionEnabled = NO;

As well as preventing selection, this also stops tableView:didSelectRowAtIndexPath: being called for the cells that have it set. (Credit goes to Tony Million for this answer, thanks!)

If you have buttons in your cells that need to be clicked, you need to instead:

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

and you also need to ignore any clicks on the cell in - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath.

If you want to disable selection for the whole table, use:

tableView.allowsSelection = NO;

(Credit to Paulo De Barros, thanks!)


Try to type:

cell.selected = NO;

It will deselect your row when needed.

In Swift3 ...

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let r = indexPath.row
    print("clicked .. \(r)")
    tableView.cellForRow(at: indexPath)?.setSelected(false, animated: true)
}

While this is the best and easiest solution to prevent a row from showing the highlight during selection

cell.selectionStyle = UITableViewCellSelectionStyleNone;

I'd like to also suggest that it's occasionally useful to briefly show that the row has been selected and then turning it off. This alerts the users with a confirmation of what they intended to select:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
     [tableView deselectRowAtIndexPath:indexPath animated:NO];
...
}

You Can also set the background color to Clear to achieve the same effect as UITableViewCellSelectionStyleNone, in case you don't want to/ can't use UITableViewCellSelectionStyleNone.

You would use code like the following:

UIView *backgroundColorView = [[UIView alloc] init];
backgroundColorView.backgroundColor = [UIColor clearColor];
backgroundColorView.layer.masksToBounds = YES;
[cell setSelectedBackgroundView: backgroundColorView];

This may degrade your performance as your adding an extra colored view to each cell.


You can also do it from the storyboard. Click the table view cell and in the attributes inspector under Table View Cell, change the drop down next to Selection to None.


You can use ....

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

You can use this

cell.selectionStyle = UITableViewCellSelectionStyleNone;

You just have to put this code into cellForRowAtIndexPath

To disable the cell's selection property:(While tapping the cell).

cell.selectionStyle = UITableViewCellSelectionStyle.None

try this

cell.selectionStyle = UITableViewCellSelectionStyleNone;

and

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

and you can also set selection style using interfacebuilder.


UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
[cell setSelected:NO animated:NO];
[cell setHighlighted:NO animated:NO];

Happy coding !!!





cocoa-touch