Skip to content
August 19, 2011 / chadmeyercodez

iOS Multi-select Table Cells

I created a way to select multiple table cells in a UITableView by making a custom UITableView along with custom UITableViewCell. I will go through some of the main features of this. You can get the complete code on github.

On initialization of the table view, a notification is created to listen for the selecting of table cells. We turn off the ability for the table to allow selection. We will handle that in the table cell itself.

- (id)initWithFrame:(CGRect)frame style:(UITableViewStyle)aStyle notification:(NSString *)notification {
    if ((self = [super initWithFrame:frame style:aStyle])) {
        // Initialization code
        self.allowsSelection = NO;

		// Create a notification to select table cells
		self.selectedTableCells = [[NSMutableArray alloc] init];
        [[NSNotificationCenter defaultCenter] addObserver: self
                                                 selector: @selector(notificationChangeSelectedCells:)
                                                     name: [NSString stringWithFormat:@"FTPUITableView_%@", notification]
                                                   object:nil];
    }
    return self;
}

The method for firing the notification first determines if the table is set up to handle multi select. If it is then it goes through some logic to determine if the cell is being asked to be selected or unselected. It will then draw the cell the way it needs to be presented.

- (void) notificationChangeSelectedCells: (NSNotification *) notification {
	
	FTPUIMultiSelectTableViewCell *notificationTableCell = (FTPUIMultiSelectTableViewCell *)[notification object];
	
	if (self.isMultiSelect) {
		
		// If the object is not a check in table cell, we are not interested in it
		if ([[notification object] isKindOfClass:[FTPUIMultiSelectTableViewCell class]]) {
			
			if ([self isTableCellSelected:[notificationTableCell rowNumber]]) {
				[self.selectedTableCells removeObject:[NSNumber numberWithInteger:[notificationTableCell rowNumber]]];
			}
			else {
				[self.selectedTableCells addObject:[NSNumber numberWithInteger:[notificationTableCell rowNumber]]];
			}
			
			// Draw the cell
			[notificationTableCell drawCell:[self isTableCellSelected:[notificationTableCell rowNumber]]];
		}
	}
	else {
		// get all the visible cells to deselect one of the cells
		NSArray *visible = [self visibleCells];
		
		for (FTPUIMultiSelectTableViewCell *current in visible) {
			if (current.rowNumber != notificationTableCell.rowNumber) {
				current.isSelected = NO;
				[current drawCell:NO];
			}
			else {
				current.isSelected = YES;
				[current drawCell:YES];
			}

		}
	}
}

The table cell has a few methods to draw the cell for presentation. This can be customized however you want your cell to look. The first method sets the properties of the cell. All the properties are needed for the table view to properly analyze the state of the cell.

- (void) drawCell:(NSIndexPath *)indexPath withSectionRows:(NSInteger)sectionRows hasSelector:(BOOL)selector isSelected:(BOOL)selected {
	
    [self setHasSelector:selector];
	[self setRowNumber:[indexPath row]];
	[self setTotalRowsInSection:sectionRows];
	[self setIsSelected:selected];
	[self drawCell:selected];
}


- (void) drawCell: (BOOL)isHighlight {
    
	// If the cell has a selector, populate the selector view
	if (self.hasSelector) {
		if (isHighlight) {
            UIImage *table_row_select = [UIImage imageNamed:@"icon_check_square.gif"];
            ((UIImageView *)self.imageView).image = [self scale:table_row_select toSize:CGSizeMake(20, 20)];
            [self.contentView setBackgroundColor:self.highlightedColor];
		}
		else {
            UIImage *hollow_image = [UIImage imageNamed:@"select_hollow.png"];
            ((UIImageView *)self.imageView).image = [self scale:hollow_image toSize:CGSizeMake(20, 20)];
            [self.contentView setBackgroundColor:self.unhighlightedColor];
		}
	}
	
	[self changeLabelColors:isHighlight];
}

- (void) changeLabelColors:(BOOL) selected {

	// Find all labels that are part of the content view
	for (UIView *current in [self.contentView subviews]) {
		
		if ([current isKindOfClass:[UILabel class]]) {
			UILabel *currentLabel = (UILabel *)current;
			if(selected) {
				[currentLabel setTextColor:[UIColor whiteColor]];
			}
			else {
				[currentLabel setTextColor:[UIColor blackColor]];
			}
		}
	}
}

When the cell is created in the table view delegate method of cellForRowAtIndexPath the cell is given the notification name as well. Then the cell is drawn given the parameter values

    NSString *arrayText = [tableResults objectAtIndex:[indexPath row]];

    static NSString *CellIdentifier = @"Cell";
    FTPUIMultiSelectTableViewCell *cell = (FTPUIMultiSelectTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        cell = [[[FTPUIMultiSelectTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

		cell.selectionStyle = UITableViewCellSelectionStyleNone;

		// Notification name
		cell.notificationName = @"multi_select";
	}

	// Creates the cell with all the necessary variables to set up custom UX presentation
	[cell drawCell:indexPath
       withSectionRows:[tableView numberOfRowsInSection:[indexPath section]]
           hasSelector:YES
            isSelected:[table isTableCellSelected:[indexPath row]]];

    return cell;

The touch event of the table cell fires of the notification

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    [[NSNotificationCenter defaultCenter] postNotificationName:[NSString stringWithFormat:@"%@%@", NotificationPrefix, [self notificationName]] object:self];
}

This shows some of the features of how to do multi select in a custom UITableView. I recommend going to iOS-multi-select, grabbing the actual project and mess around with it. I would definitely be interested in any comments or concerns.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: