Resolved Strange behavior with grouped UITableView

Discussion in 'iOS Programming' started by straber, Oct 4, 2012.

  1. straber, Oct 4, 2012
    Last edited: Oct 4, 2012

    straber macrumors member

    Joined:
    Jul 3, 2012
    #1
    I've encountered some behavior with the UITableView that I can't explain and was wondering if anyone had encountered this or had an explanation. What's happening is I have a grouped table with 2 sections. When a user selects a row I want to add a checkmark to that row and remove the checkmark from the previously selected row in that section. Sounds simple enough, however, when I select the first row in the first section, it also puts a checkmark on the fourth or fifth row of the second section. Additionally, if I scroll up and down the table quickly, the checkmark will move to different rows. Here is the code if anyone wants to try it out and see if you get the same behavior:

    ViewController.h

    Code:
    #import <UIKit/UIKit.h>
    
    @interface ViewController : UITableViewController
    
    @property (nonatomic, strong) NSArray *sectionZeroStrings;
    @property (nonatomic, strong) NSArray *sectionOneStrings;
    @property (nonatomic, strong) NSIndexPath *lastSectionZeroPath;
    @property (nonatomic, strong) NSIndexPath *lastSectionOnePath;
    
    @end
    ViewController.m

    Code:
    #import "ViewController.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    @synthesize sectionOneStrings;
    @synthesize sectionZeroStrings;
    @synthesize lastSectionOnePath;
    @synthesize lastSectionZeroPath;
    
    - (void)viewDidLoad
    {
    
        [super viewDidLoad];
    
        sectionZeroStrings = [[NSArray alloc] initWithObjects:@"First", @"Second", @"Third", @"Fourth", @"Fifth", @"Sixth", @"Seventh", @"Eighth", nil];
    
        sectionOneStrings = [[NSArray alloc] initWithObjects:@"Uno", @"Dos", @"Tres", @"Quatro", @"Cinco", @"Seis", @"Siete", nil];
    }
    
    - (void)viewDidUnload
    {
        [super viewDidUnload];
    
        // Release any retained subviews of the main view.
    }
    
    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
    {
        return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
    }
    
    #pragma mark - Table view data source
    
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
        return 2;
    }
    
    - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    
        if (0 == section) {
            return @"First Alarm";
        }
        else if (1 == section) {
            return @"Second Alarm";
        }    
    
        return 0;
    
    }
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    
        if (0 == section) {
    
            return [sectionZeroStrings count];
    
        }
    
        else if(1 == section) {
    
            return [sectionOneStrings count];
    
        }
    
        return 0;
    
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
        static NSString *CellIdentifier = @"Cell";
    
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    
        if (nil == cell) {
    
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    
        }
    
        // Configure the cell...
    
        switch ([indexPath section]) {
    
            case 0:
                cell.textLabel.text = (NSString *)[sectionZeroStrings objectAtIndex:[indexPath row]];
    
                break;
    
            case 1:
                cell.textLabel.text = (NSString *)[sectionOneStrings objectAtIndex:[indexPath row]];
                break;
            default:
                break;
        }
    
        return cell;
    
    }
    
    #pragma mark - Table view delegate
    
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {    
    
        [tableView deselectRowAtIndexPath:indexPath animated:YES];
    
        switch ([indexPath section]) {
    
            case 0:
            {
    
                if (lastSectionZeroPath) {
    
                    UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:lastSectionZeroPath];
    
                    oldCell.accessoryType = UITableViewCellAccessoryNone;
                }
                lastSectionZeroPath = indexPath;
            }
                break;
            case 1:
            {
    
                if (lastSectionOnePath) {
    
                    UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:lastSectionOnePath];
                    oldCell.accessoryType = UITableViewCellAccessoryNone;
                }
                lastSectionOnePath = indexPath;
            }
                break;
            default:
                break;
        }
    
        UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath];
        newCell.accessoryType = UITableViewCellAccessoryCheckmark;
    }
    
    @end
    Will someone please try this out for me and see if you get the same behavior and can come up with any explanation?

    Thank you for any help with this!!
     
  2. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
  3. straber thread starter macrumors member

    Joined:
    Jul 3, 2012
    #3
    Bingo! That was exactly my problem, I was forgetting the TableViews reuse cells to save memory, and it was dequeueing a cell with a checkmark and I wasn't removing the check mark in cellForRowAtIndexPath:

    Thanks for the quick reply...
     

Share This Page