开发者

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 addSubview in cellForRowAtIndexPath: 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 drawRect. I can get text and images to draw perfectly, using drawAtPoint but this doesn't appear to work for UIButtons.

Adding the button as a subview of [self contentView] (in my subclasses drawRect) 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 tableView:cellForRowAtIndexPath

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]);
}


If all of the UITableViewCells are the same format, just with different information, I would suggest making a subclass of UITableViewCell which knows how to format the cell with some kind of Model object, and hooked up to it's own nib. That way, you can load up the new cell easily in your cellForRowAtIndexPath: method, and it should speed up your app significantly. It's also much easier to make changes to the custom cells, and is easier to implement. There are tons of tutorials online about how to do this. Here is one I just found on google. Hope that helps!


You can't really draw an UIButton in -drawRect:, unless you really create a button from scratch (i.e. without using the UIButton class). You can however change the frame of an UIButton in -drawRect. You might need to call -setNeedsDisplay inside your -tableView:cellForRowAtIndexPath: method to force drawRect: to be executed.

The code for the UITableViewCell subclass could look like the following:

@synthesize button = _button;

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
   self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
   if (self) 
   {         
      _button = [[UIButton buttonWithType:UIButtonTypeRoundedRect] retain];
      [self.contentView addSubview:_button];
   }
   return self;
}

- (void)dealloc 
{
    [_button release];
    [super dealloc];    
}

- (void)drawRect:(CGRect)frame
{   
    _button.frame = CGRectMake(20.0f, 5.0f, 100.0f, 30.0f);
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜