Custom button table cell

December 9th, 2010
#ui

I wrote this custom cell that ultimately was axed because it didn't fit into the UI that was later revised. I thought it was a shame to waste it so here it is in the full.

It works by allowing you to define how buttons should appear in a cell, each is given an equal size and spacing is worked out on the fly. When a button is clicked it fires off a notification indicating that it was pressed which means that the button/cell doesn't care what tableview it is included in so increasing encapsulation.

.h

#import <UIKit/UIKit.h>


@interface ButtonCellController : UITableViewCell {
	@private
	NSDictionary *dict;
}

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier withArray:(NSArray *)array;

@end

As my requirements where that all my table cells contained the same number of buttons I was able to pass those in at init. If your needs are for multiple buttons numbers you will need to be more creative and pass it as a property with the setup happening in that custom setter

.m

#import "ButtonCellController.h"

@implementation ButtonCellController

static int const buttonPadding = 5;

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier withArray:(NSArray *)array{
	if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) {

		int numberOfButtons = [array count];
		int maxButtonWidth = ((self.frame.size.width - (buttonPadding*2)) - ((numberOfButtons - 1) * buttonPadding))/numberOfButtons;

		for (int i = 0; i < numberOfButtons; i++) {

			NSDictionary *cellContent = [array objectAtIndex:i];

			UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];

			int x;

			if (i != 0) {
				UIButton *previousButton = (UIButton *)[self.contentView viewWithTag:i];
				x = (previousButton.frame.origin.x + previousButton.frame.size.width + buttonPadding);
			}else {
				x = buttonPadding;
			}

			button.frame = CGRectMake(x, 5, maxButtonWidth, 80);

			[button setBackgroundImage:[UIImage imageNamed:[cellContent objectForKey:@"unPressedImage"]] forState:UIControlStateNormal];

			button.tag = (i+1);
			[button addTarget:self action:@selector(coverButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
			[self.contentView addSubview:button];

			CustomLabel *label = [[CustomLabel alloc] initWithStyle:CustomLabelStyleValue]; //i'll post an article about this UILabel extension
			label.frame = CGRectMake(x, (button.frame.size.height + buttonPadding), maxButtonWidth, 44);
			label.text = NSLocalizedString([cellContent objectForKey:@"name"], @"");
			label.textAlignment = UITextAlignmentCenter;
			label.lineBreakMode = UILineBreakModeWordWrap;
			label.numberOfLines = 2;

			[self.contentView addSubview:label];
		}

		self.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"account-Button.png"]];
		self.selectionStyle = UITableViewCellSelectionStyleNone;
	}

	return self;
}

#pragma mark -
#pragma mark IBAction methods

-(IBAction)coverButtonClicked:(id)sender{

	UIButton *button = (UIButton *)sender;
	UITableViewCell *cell = (UITableViewCell *)[[button superview] superview];
	NSMutableDictionary *extraInfo = [[NSMutableDictionary alloc] init];
	[extraInfo setObject:[NSNumber numberWithInt:button.tag] forKey:@"value"];
	NSNotification *note = [NSNotification notificationWithName:@"buttonPressed" object:cell userInfo:extraInfo];
	[[NSNotificationCenter defaultCenter] postNotification:note];
}

- (void)dealloc {
	[dict release];

    [super dealloc];
}

@end

What do you think? Let me know by getting in touch on Twitter - @wibosco