ThisDarkTao ThisDarkTao - 9 months ago 45
iOS Question

UITableViewCell subclass, how to draw buttons?

I'm making an app that needs three buttons in each tableview cell. I tried just adding the buttons to the cell using

but this resulted in slow/janky scrolling with more than 6 or 7 rows.

I did some research online and have followed Apple's example of subclassing the UITableViewCell and drawing everything in
. I can get text and images to draw perfectly, using
but this doesn't appear to work for UIButtons.

Adding the button as a subview of
[self contentView]
(in my subclasses
) just results in even worse scroll lag than before.

Does anyone know how to get a button to draw properly within my UITableViewCell subclass?

Getting this right is crucial to the entire app so any help would be greatly appreciated!

UPDATE: Here is the code used for for

static NSString *CellIdentifier = @"CustomCell";

AHCustomCell * cell = (AHCustomCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) {
AHCustomCell * customCell = [[[AHCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
customCell.frame = CGRectMake(0.0, 0.0, 320.0, 55.0);
cell = customCell;


The following code gives three buttons and no jaggy scrolling. Using tags, you can reset the text of the buttons depending on the row. This is illustrated for button 1 (which adjusts its title according to the row number). The button1Pressed: method illustrated figures out what row the button press came from. Hope this will be helpful.

- (UITableViewCell *)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    static NSString* cellIdentifier = @"Cell";

    // see if there's a cell available to recylce
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    if (!cell)
        // there's no cell to recycle, so make a new one
        // add three buttons to it and tag them so we can alter their contents later

        cell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:cellIdentifier];

        UIButton* button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        [button1 setTitle:@"Button 1" forState:UIControlStateNormal];
        [button1 setFrame:CGRectMake(4.0, 15.0, 110, 30.0)];
        [button1 setTag:101];
        [button1 addTarget:self action:@selector(button1Pressed:) forControlEvents:UIControlEventTouchUpInside];
        [[cell contentView] addSubview:button1];

        UIButton* button2 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        [button2 setTitle:@"Button 2" forState:UIControlStateNormal];
        [button2 setFrame:CGRectMake(120.0, 15.0, 80.0, 30.0)];
        [button2 setTag:102];
        [button1 addTarget:self action:@selector(button2Pressed:) forControlEvents:UIControlEventTouchUpInside];
        [[cell contentView] addSubview:button2];

        UIButton* button3 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        [button3 setTitle:@"Button 3" forState:UIControlStateNormal];
        [button3 setFrame:CGRectMake(210, 15.0, 80.0, 30.0)];
        [button3 setTag:103];
        [button3 addTarget:self action:@selector(button3Pressed:) forControlEvents:UIControlEventTouchUpInside];
        [[cell contentView] addSubview:button3];


    // either on a recycled cell or on the cell just created, set the contents

    UIButton* button1 = (UIButton*)[[cell contentView] viewWithTag:101];
    [button1 setTitle: [NSString stringWithFormat:@"Button 1 - %d", [indexPath row]] forState:UIControlStateNormal];

    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    return cell;

- (void) button1Pressed: (UIButton*) button
   CGPoint buttonCentre = [button convertPoint:[button center] toView:[self tableView]];

    NSLog(@"Button 1 Pressed on row %d", [[[self tableView] indexPathForRowAtPoint:buttonCentre] row]);