UITableViewCell stays highlighted

Discussion in 'iOS Programming' started by Colonial94, Oct 9, 2008.

  1. Colonial94 macrumors newbie

    Joined:
    Sep 28, 2008
    #1
    I created a custom cell for my table view and for the most part everything seems to be working fine, but when I select one of the rows (which takes me to another UIView), then come back from the subsequent view via the nav controller, the cell is still selected. If I select a new cell, it works, but then that one is highlighted when I come back.

    Has anyone run into this before? Any ideas what could be going wrong?
     
  2. xnakx macrumors newbie

    Joined:
    Oct 5, 2008
    #2
    deselect it
    Code:
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    	[tableView deselectRowAtIndexPath:indexPath animated:YES];
    }
     
  3. PhoneyDeveloper macrumors 68040

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #3
    You're not using a UITableViewController are you? If you are pushing a new view in response to selection then deselect the row in viewWillAppear:

    Code:
    - (void)viewWillAppear:(BOOL)animated
    {
    	// Unselect the selected row if any
    	NSIndexPath*	selection = [self.tableView indexPathForSelectedRow];
    	if (selection)
    		[self.tableView deselectRowAtIndexPath:selection animated:YES];
    
    	[self.tableView reloadData];
    }
    
    This way the row deselects when the table is coming back into view and there is a visual reminder of what row was selected when you moved to the new view.
     
  4. Colonial94 thread starter macrumors newbie

    Joined:
    Sep 28, 2008
    #4
    Thanks

    Phoney & xnakx - Thanks. Both solutions work, but I am opting for Phoney's approach as it provides the visual reminder as he indicated.

    Phoney - I am using a UIViewController which operates as the UITableViewDelegate & UITableViewDataSource. Is that why I need to put this in my code? I have other tableviews which don't require it.

    Thanks!
     
  5. PhoneyDeveloper macrumors 68040

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #5
    The TableView Programming guide recommends that three methods be added to a UIViewController that manages a TableView. They aren't needed if you're using a UITableViewController because it already implements them. I also add a fourth method that I think should be implemented. They aren't all required for every table as some don't use the features that they apply to, but I add them to my code.

    Regarding the un-selection of the row after it's been selected I think the guide recommends un-selecting it immediately but I think that some of the apple apps don't do it that way and I think it makes more sense the way I suggested.


    Code:
    // The following three methods must be implented in a UIViewController
    // that manages a UITableView but which isn't a UITableViewController
    //	==============================================================
    //	setEditing:animated:
    //	==============================================================
    
    - (void)setEditing:(BOOL)editing animated:(BOOL)animated
    {
    	[super setEditing:editing animated:animated];
    	[self.tableView setEditing:editing animated:animated];
    }
    
    //	==============================================================
    //	viewWillAppear:
    //	==============================================================
    
    - (void)viewWillAppear:(BOOL)animated
    {
    	// Unselect the selected row if any
    	NSIndexPath*	selection = [self.tableView indexPathForSelectedRow];
    	if (selection)
    		[self.tableView deselectRowAtIndexPath:selection animated:YES];
    
    	[self.tableView reloadData];
    }
    
    //	==============================================================
    //	viewDidAppear:
    //	==============================================================
    
    - (void)viewDidAppear:(BOOL)animated
    {
    	//	The scrollbars won't flash unless the tableview is long enough.
    	[self.tableView flashScrollIndicators];
    }
    
    - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
    {
    	[self.tableView flashScrollIndicators];
    }
    
     
  6. Inkreaser macrumors newbie

    Joined:
    Nov 25, 2009
    #6
    Hi,

    I am experiencing the same problem with rows not de-selecting when the view re-appears, and I am also using a UITableView inside a UIViewController. However, I tried PhoneyDeveloper's solution and got 3 error messages which read:

    "Request for member 'tableView' in something not a structure or union"

    I THINK that the method can't reach my tableView. In case it helps, I am using a UITabBarController and on the first tab I have a UINavigationController for my hierarchical tables, and the first UIViewController in this has my first list. It's in this class that I am inserting the code. Does anyone know how to get around this error?

    For the record, xnakx's solution does work, but I prefer the look of the other approach.
     
  7. PhoneyDeveloper macrumors 68040

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #7
    You need a @property named tableView that holds your table view. Or you need to change the code I showed to reference whatever you call your table view. Is this not obvious?
     
  8. Inkreaser macrumors newbie

    Joined:
    Nov 25, 2009
    #8
    Hi PhoneyDeveloper,

    Thank you. I've only been doing this for a few weeks now, it wasn't obvious to me so I appreciate your help.

    I've declared clientsTableView in my header and linked it as an IBOutlet in IB. Whilst it's working, I don't get the visual reminder as the tableView is re-appearing already de-selected, unless I remove the following line:

    [self.clientsTableView reloadData];

    Do you know why? I thought I could get the visual reminder even with this code?

    Thanks again for your help.
     
  9. PhoneyDeveloper macrumors 68040

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #9
    Either remove the reloadData completely or move it to be before the deselection code or use

    Code:
    [self.tableView beginUpdates];
    [self.tableView endUpdates];
    
    This is something that's a little screwy and has changed significantly between OS 2.2.1 and 3.0.

    In general the reloadData or beginUpdates/endUpdates was needed in OS 2.x because there were a number of UI glitches that occurred in the table views without it. Most of these have been fixed in 3.x. However there are still problems when the device rotates and another view has been pushed. So the sequence of events: push view controller with a table, push another view controller, rotate the device, pop the view controller, can result in UI glitches. I filed a bug on one of them and Apple closed it as "behaves as designed." Because of that I still have the reloadData/beginUpdates/endUpdates code in many places. beginUpdates/endUpdates didn't work right for this in OS 2.2.1 but it does in OS 3.x. I'm still supporting 2.2.1 so I have code like this

    Code:
    - (void)reloadRowHeights
    {
    	if (hasv3Tables())
    	{
    		[self.tableView beginUpdates];
    		[self.tableView endUpdates];
    	}
    	else
    	{
    		[self.tableView reloadData];
    	}
    }
    - (void)viewWillAppear:(BOOL)animated
    {
    	[self reloadRowHeights];	// Need this if the device rotated while we weren't visible
    
    	// Unselect the selected row if any
    	NSIndexPath*	selection = [self.tableView indexPathForSelectedRow];
    	if (selection)
    		[self.tableView deselectRowAtIndexPath:selection animated:YES];
    
    }
    
    This may only be required if you have a table with variable row heights or have section/table headers or footers. The row heights and the header/footer heights can change if the device rotates.
     
  10. Inkreaser macrumors newbie

    Joined:
    Nov 25, 2009
    #10
    Thank you for all your help PhoneyDeveloper. I tried reloadData before and after the deselection but I couldn't get the visual reminder to work, so I've removed it for now as I don't need it at this stage, and it's now working great. Thanks for a great explanation and some useful source code!
     

Share This Page