Bug Check: Cell improperly getting settings from another cell

Discussion in 'iOS Programming' started by Fontano, Jan 27, 2009.

  1. Fontano macrumors member

    Joined:
    Jun 27, 2008
    #1
    Okay, so.
    I am trying to have a toggle switch, that in a certain state some rows are visible. Some are not.

    Here is a VERY basic example, that shows the error.

    Create a blank Navigation project, with the TableView.
    Change it in IB to a GroupTable, then drop this code in place.
    So you can see what I am talking about.

    The first section, the first row is set to red text.
    The Second section, the first row is set to black. When the app first starts, the toggle switch is off, so there is no second row.

    Click on the first row in the second section, and this toggles the switch. Reloads the table, and my second row appears.

    However now the FIRST row in the section section, it's text goes to red.
    toggle it off, and it goes back to black.

    As you can see from the code, the logic of the formating of the cell the color settings are never applied to the cell in the second section.

    So any input on if I am coding this right, or is just a bug would greatly appreciated:

    Code:
    #import "RootViewController.h"
    #import "TestingCellBugAppDelegate.h"
    
    
    @implementation RootViewController
    
    BOOL switchTestState = FALSE;
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
        // Release anything that's not essential, such as cached data
    }
    
    #pragma mark Table view methods
    
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
        return 2;
    }
    
    
    // Customize the number of rows in the table view.
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    	if (section == 0)
    		return 1;
    	if (section == 1)
    		if (switchTestState)
    			return 2;
    		else
    			return 1;
    
    	return 1;
    }
    
    - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    	if (section == 0)
    		return @"Static Section";
    	if (section == 1)
    		return @"Dynamic Section";
    	
    	return nil;
    }
    
    
    // Customize the appearance of table view cells.
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        
        static NSString *CellIdentifier = @"Cell";
        
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
        }
        
        // Set up the cell...
    	if (indexPath.section == 0) {
    		[cell setTextColor:[UIColor redColor]];
    		[cell setText:@"Static No Change"];
    	}
    
    	if (indexPath.section == 1) {
    		if (indexPath.row == 0) 
    			[cell setText:@"Toggle Switch"];
    		if (indexPath.row == 1)
    			[cell setText:@"Is Turned On/Off"];
    	}	
    
    	return cell;
    }
    
    
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    	if ((indexPath.section == 1) && (indexPath.row == 0)) {
    		if (switchTestState)
    			switchTestState = FALSE;
    		else
    			switchTestState = TRUE;
    		[[self tableView] reloadData];
    	}
    
    	[tableView deselectRowAtIndexPath:indexPath animated:YES];
    	
    }
    
    - (void)dealloc {
        [super dealloc];
    }
    
    
    @end
    
     
  2. eddietr macrumors 6502a

    Joined:
    Oct 29, 2006
    Location:
    Virginia
    #2
    So the issue is that cells get reused. In this case, initially you have two table cells.

    One has the text "Toggle..." and one is "Static...."

    When the table is drawn the second time, you have 3 cells. But two are being re-used. And (at least in 2.2 simulator) they are reused as such:

    First the cell "Is Turned On/Off" is the same cell that was previously "Toggle...". So the text is changed, but the color stays the same.

    Next you have the cell "Is Turned On/Off" which is actually the same cell that previously read "Static..." So you changed the text, but did not change the text color of that cell. That is why it is red.

    Then a new cell is created. This new cell is set to Red and the text is set to "Static..."

    So the fix is quite simple, in the code that sets the text for Section 1 (second section), you want to just make sure to set the color to black. Reason being that you do not know if the cell you are drawing was previously red.

    And BTW, if for some reason you really don't want cells to be reused from one section to another, then you need to use different CellIdentifiers for cells in one section versus the other. Right now you have only one CellIdentifier "Cell", so cells from one section are no different from the other.

    Which in this case is probably just fine, so long as you remember to reset the color as needed.

    I hope that helps.
     
  3. Fontano thread starter macrumors member

    Joined:
    Jun 27, 2008
    #3
    That does help, I will try some of your ideas and let you know.

    But first to dig through the new SDK Update.
     

Share This Page