50

I have a uitableview cell highlighted when a user selects it and then is pushed to a detail view. I would like the cell to be unhighlighted when they return to the table view view controller.

how would I go about accomplishing this?

I'm guessing [cell.textLabel setHighlighted:NO]; in viewWillAppear, but cell is undeclared if I put it there.

thanks for any help

hanumanDev
  • 6,592
  • 11
  • 82
  • 146

6 Answers6

108

If you using UITableViewController subclass then just set property

self.clearsSelectionOnViewWillAppear = YES;

else in viewWillAppear just call

NSIndexPath *indexPath = self.tableView.indexPathForSelectedRow;
if (indexPath) {
    [self.tableView deselectRowAtIndexPath:indexPath animated:animated];
}

// MARK: - Swift 3
if let indexPath = tableView.indexPathForSelectedRow {
    tableView.deselectRow(at: indexPath, animated: true)
}
nickdnk
  • 4,010
  • 4
  • 24
  • 43
iiFreeman
  • 5,165
  • 2
  • 29
  • 42
  • 4
    Note: `clearsSelectionOnViewWillAppear` works most of the time. It will not work if you "swipe to back" on iOS7 back to the tableViewController. The 2nd method works all the time, with added nice animation. – Byte Dec 04 '13 at 17:49
  • 4
    I think it's better to use viewWillAppear than viewDidAppear - the animation-timing looks more consistent with what UITableViewController does. – chrisbuchholz Apr 15 '14 at 20:08
  • Matter what you want, sure will appear good, maybe even better ) – iiFreeman Apr 15 '14 at 21:31
  • 3
    In swift you do: `if let indexPath = self.tableView.indexPathForSelectedRow{ self.tableView.deselectRowAtIndexPath(indexPath, animated: animated) }` – Werner Kratochwil Sep 29 '16 at 16:16
  • 2
    Is better to use `viewWillAppear` than `viewDidAppear`, the effect will be similar to `clearsSelectionOnViewWillAppear` – Heberti Almeida Oct 20 '16 at 08:27
22

Swift 3.0

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

    if let selectionIndexPath = self.tableView.indexPathForSelectedRow {
        self.tableView.deselectRow(at: selectionIndexPath, animated: animated)
    }
}
jbouaziz
  • 1,484
  • 1
  • 12
  • 24
Dustin Spengler
  • 5,478
  • 4
  • 28
  • 36
  • (You could probably remove the `self.` before each invocation of `tableView`, for some cleaner and swiftier code.) – royalmurder Sep 13 '17 at 09:40
  • For sure. I just like to be explicit about variables that belong to the controller so I don't get them confused with local variables. Just a personal preference. – Dustin Spengler Sep 13 '17 at 18:01
  • @royalmurder You could definitely remove it; it's just a matter of style. I personally prefer to use self to differentiate properties of the class from ivars, as Dustin mentioned. Regardless, the use of self here has no impact on the functionality at hand. – vikzilla Feb 25 '18 at 22:51
  • 1
    Worked out of the box in Swift 4 - thanks so much. Tip: You can set `animated:` to `true` (which does the same thing as setting it to `animated` like in this answer) or `false`. – velkoon Dec 09 '18 at 01:27
7

try

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Deselect the row which was tapped
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
}
pkamb
  • 33,281
  • 23
  • 160
  • 191
Girish
  • 4,692
  • 4
  • 35
  • 55
6

I decided to make this an answer instead of a comment.

If you are using storyboard: Click on your UITableViewController -> Check the "Selection: Clear on Appearance" box

AlexanderN
  • 2,610
  • 1
  • 26
  • 42
4

swift 3

func clearOnAppearance() {
    for indexPath in tableView.indexPathsForSelectedRows ?? [] {
        tableView.deselectRow(at: indexPath, animated: true)
    }
}
neoneye
  • 50,398
  • 25
  • 166
  • 151
1

Or some inelegant way =)

NSArray *arrayWithPaths = [tableView indexPathsForVisibleRows];
for (NSIndexPath *path in arrayWithPaths)
{
    [tableview deselectRowAtIndexPath:path animated:NO];
}
pkamb
  • 33,281
  • 23
  • 160
  • 191
alex
  • 2,121
  • 1
  • 18
  • 24