Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to deselect a selected UITableView cell?

I am working on a project on which I have to preselect a particular cell.

I can preselect a cell using -willDisplayCell, but I can't deselect it when the user clicks on any other cell.

- (void)tableView:(UITableView*)tableView 
        willDisplayCell:(UITableViewCell*)cell
        forRowAtIndexPath:(NSIndexPath*)indexPath
{ 
    AppDelegate_iPad *appDelegte = 
      (AppDelegate_iPad *)[[UIApplication sharedApplication] delegate];

    if ([appDelegte.indexPathDelegate row] == [indexPath row])
    {
        [cell setSelected:YES];    
    } 
}

- (void)tableView:(UITableView *)tableView 
        didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    AppDelegate_iPad *appDelegte = 
      (AppDelegate_iPad *)[[UIApplication sharedApplication] delegate];

    NSIndexPath *indexpath1 = appDelegte.indexPathDelegate;
    appDelegte.indexPathDelegate = indexPath;
    [materialTable deselectRowAtIndexPath:indexpath1 animated:NO];
}

Can you help?

like image 468
Ram Avatar asked Oct 19 '10 11:10

Ram


People also ask

How do I delete a cell in UITableView?

So, to remove a cell from a table view you first remove it from your data source, then you call deleteRows(at:) on your table view, providing it with an array of index paths that should be zapped. You can create index paths yourself, you just need a section and row number.

What is deselectRow?

deselectRow(at:animated:)Deselects a row that an index path identifies, with an option to animate the deselection.

How can we use a reusable cell in UITableView?

For performance reasons, a table view's data source should generally reuse UITableViewCell objects when it assigns cells to rows in its tableView(_:cellForRowAt:) method. A table view maintains a queue or list of UITableViewCell objects that the data source has marked for reuse.


21 Answers

use this code

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
 {
    //Change the selected background view of the cell.
     [tableView deselectRowAtIndexPath:indexPath animated:YES];
 }

Swift 3.0:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    //Change the selected background view of the cell.
    tableView.deselectRow(at: indexPath, animated: true)
}
like image 188
Saikiran Komirishetty Avatar answered Oct 05 '22 06:10

Saikiran Komirishetty


Use the following method in the table view delegate's didSelectRowAtIndexpath (Or from anywhere)

[myTable deselectRowAtIndexPath:[myTable indexPathForSelectedRow] animated:YES];
like image 27
Shamitha Avatar answered Oct 05 '22 06:10

Shamitha


It might be useful to make an extension in Swift for this.

Swift 4 and Swift 5:

Swift extension (e.g. in a UITableViewExtension.swift file):

import UIKit

extension UITableView {

    func deselectSelectedRow(animated: Bool)
    {
        if let indexPathForSelectedRow = self.indexPathForSelectedRow {
            self.deselectRow(at: indexPathForSelectedRow, animated: animated)
        }
    }

}

Use e.g.:

override func viewWillAppear(_ animated: Bool)
{
    super.viewWillAppear(animated)

    self.tableView.deselectSelectedRow(animated: true)
}
like image 20
Thomas Neuteboom Avatar answered Oct 05 '22 06:10

Thomas Neuteboom


Try this:

for (NSIndexPath *indexPath in tableView.indexPathsForSelectedRows) {
    [tableView deselectRowAtIndexPath:indexPath animated:NO];
}
like image 27
ikosdroid Avatar answered Oct 05 '22 05:10

ikosdroid


Please check with the delegate method whether it is correct or not. For example;

-(void) tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath

for

-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
like image 43
jfalexvijay Avatar answered Oct 05 '22 05:10

jfalexvijay


Swift 4:

tableView.deselectRow(at: indexPath, animated: true)
like image 32
Andrea.Ferrando Avatar answered Oct 05 '22 05:10

Andrea.Ferrando


This is a solution for Swift 4

 in tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)

just add

tableView.deselectRow(at: indexPath, animated: true)

it works like a charm

example:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
//some code
}
like image 42
tBug Avatar answered Oct 05 '22 05:10

tBug


In addition to setting the cell as selected, you also need to inform the tableView that the cell is selected. Add a call to -tableView:selectRowAtIndexPath:animated:scrollPosition: to your willDisplayCell: method: and you will be able to deselect it as normal.

- (void)tableView:(UITableView*)tableView 
  willDisplayCell:(UITableViewCell*)cell
forRowAtIndexPath:(NSIndexPath*)indexPath
{ 
    AppDelegate_iPad *appDelegte = (AppDelegate_iPad *)[[UIApplication sharedApplication] delegate];

    if ([appDelegte.indexPathDelegate row] == [indexPath row])
    {
        // SELECT CELL
        [cell setSelected:YES]; 
        // TELL TABLEVIEW THAT ROW IS SELECTED
        [tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];   
    } 
}

Be sure to use UITableViewScrollPositionNone to avoid odd scrolling behavior.

like image 35
Drew C Avatar answered Oct 05 '22 06:10

Drew C


Based on saikirans solution, I have written this, which helped me. On the .m file:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    if(selectedRowIndex && indexPath.row == selectedRowIndex.row) {

        [tableView deselectRowAtIndexPath:indexPath animated:YES];
        selectedRowIndex = nil;

    }

    else {  self.selectedRowIndex = [indexPath retain];   }

    [tableView beginUpdates];
    [tableView endUpdates];

}

And on the header file:

@property (retain, nonatomic) NSIndexPath* selectedRowIndex;

I am not very experienced either, so double check for memory leaks etc.

like image 41
Yunus Nedim Mehel Avatar answered Oct 05 '22 06:10

Yunus Nedim Mehel


This should work:

[tableView deselectRowAtIndexPath:indexpath1 animated:NO];

Just make sure materialTable and tableView are pointing to the same object.

Is materials connected to the tableView in Interface Builder?

like image 43
Jordan Avatar answered Oct 05 '22 04:10

Jordan


If you want to select any table cell with the first click and deselect with the second, you should use this code:

- (void)tableView:(UITableView *)tableView 
        didSelectRowAtIndexPath:(NSIndexPath *)indexPath {   

    if (self.selectedIndexPath && 
        [indexPath compare:self.selectedIndexPath] == NSOrderedSame) {

        [tableView deselectRowAtIndexPath:indexPath animated:YES];
         self.selectedIndexPath = nil;
    } 
    else {
        self.selectedIndexPath = indexPath;
    }
}
like image 35
CHiP-love-NY Avatar answered Oct 05 '22 06:10

CHiP-love-NY


Swift 4:

func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
    let cell = tableView.cellForRow(at: indexPath)
    if cell?.isSelected == true { // check if cell has been previously selected
        tableView.deselectRow(at: indexPath, animated: true)
        return nil
    } else {
        return indexPath
    }
}
like image 36
PowerSurge Avatar answered Oct 05 '22 06:10

PowerSurge


Swift 2.0:

tableView.deselectRowAtIndexPath(indexPath, animated: true)
like image 32
Anit Kumar Avatar answered Oct 05 '22 05:10

Anit Kumar


Swift 3/4

In ViewController:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: true)
}

In Custom Cell:

override func awakeFromNib() {
    super.awakeFromNib()
    selectionStyle = .none
}
like image 28
Sevy11 Avatar answered Oct 05 '22 05:10

Sevy11


try this

[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
like image 36
EnasAZ Avatar answered Oct 05 '22 05:10

EnasAZ


NSIndexPath * index = [self.menuTableView indexPathForSelectedRow];
[self.menuTableView deselectRowAtIndexPath:index animated:NO];

place this code according to your code and you will get your cell deselected.

like image 3
rahulchona Avatar answered Oct 05 '22 04:10

rahulchona


Swift 3.0:

Following the protocol conformance section of the ray wenderlich swift style guide, to keep related methods grouped together, put this extension below your view controller class like that:

// your view controller
class MyViewcontroller: UIViewController {
  // class stuff here
}

// MARK: - UITableViewDelegate
extension MyViewcontroller: UITableViewDelegate {
      // use the UITableViewDelegate method tableView(_:didSelectRowAt:)
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        // your code when user select row at indexPath

        // at the end use deselectRow
        tableView.deselectRow(at: indexPath, animated: true)
    }
}
like image 2
ronatory Avatar answered Oct 05 '22 06:10

ronatory


Can you try this?

- (void)tableView:(UITableView *)tableView 
  didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    AppDelegate_iPad *appDelegte = 
    (AppDelegate_iPad *)[[UIApplication sharedApplication] delegate];
    NSIndexPath *indexpath1 = appDelegte.indexPathDelegate;
    appDelegte.indexPathDelegate = indexPath;

    UITableViewCell *prevSelectedCell = [tableView cellForRowAtIndexPath: indexpath1];
    if([prevSelectedCell isSelected]){
       [prevSelectedCell setSelected:NO];
    }
}

It worked for me.

like image 3
Dattatraya Anarase Avatar answered Oct 05 '22 05:10

Dattatraya Anarase


Swift

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    // your code

    // your code

    // and use deselect row to end line of this function

    self.tableView.deselectRowAtIndexPath(indexPath, animated: true)

}
like image 2
Programer_saeed Avatar answered Oct 05 '22 05:10

Programer_saeed


func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: true)
}
like image 1
Aayushi Avatar answered Oct 05 '22 04:10

Aayushi


Swift 3

I've run into this as well - when you navigate or unwind back to the table view it usually doesn't deselect the previously selected row for you. I put this code in the table view controller & it works well:

override func viewDidAppear(_ animated: Bool) {
    if let lastSelectedRow = tableView.indexPathForSelectedRow {
        tableView.deselectRow(at: lastSelectedRow, animated: true)
    }
}
like image 1
Trev14 Avatar answered Oct 05 '22 04:10

Trev14