6 Replies Latest reply: Jan 28, 2011 5:16 PM by RayNewbie
AlmightySi Level 1 Level 1 (0 points)
Hi,

I've made a custom TableViewCell and added two buttons on it to change a quantity label on the cell itself. Obviously what I'm needing to do is when the + button is pressed, the quantity in that particular cell is raised. The same for the subtract button on the cell.

So far I have made the table view with the custom cells, added targets to the buttons when creating the cells and have set the tag for the buttons to be the row index for for reference.

But now my problem. In the targeted actions, how do I add and subtract the quantity for that particular cells quantity? I have the set the buttons tag as the index row so I can reference the cell, but I don't know how to change the cells quantity value from the action.

Any help would be appreciated,

Thanks.

iMac 27" i5, Mac OS X (10.6.4)
  • 1. Re: How to change text on a custom TableViewCell with a button on the cell
    RayNewbie Level 5 Level 5 (6,810 points)
    Hi Si -
    AlmightySi wrote:
    I have the set the buttons tag as the index row so I can reference the cell, but I don't know how to change the cells quantity value from the action.

    Once you have the address of the cell, there are two good ways to locate any of its subviews:

    1) If the cell is an instance of a custom subclass, you could make properties for all the subviews. Then just code something like

    cell.quantityLabel.text = [NSString stringWithFormat:@"%d", cell.quantityValue++];


    2) If the cell is an instance of UITableViewCell, you could assign unique tags to all the subviews. Then you could find the quantity label like this:

    UILabel *quantityLabel = [cell viewWithTag:kQuantityLabel];
    int currentValue = [quantityLabel.text intValue];
    quantityLabel.text = [NSString stringWithFormat:@"%d", currentValue + 1];

    In case I've misunderstood, and your primary problem is locating the cell which contains the button, it might be better to assign the same tag number to both the button and the cell when the cell is created. This would allow you to find the cell with [tableView viewWithTag:button.tag] in the action method without caring about the index path.

    - Ray
  • 2. Re: How to change text on a custom TableViewCell with a button on the cell
    AlmightySi Level 1 Level 1 (0 points)
    Thanks Ray, nice post.

    The code you supplied for changing the label text did help, but it was locating the cell that the button is located on which is my problem. I may well be missing something obvious here, but I cant seem to get this working.

    Is it fine to get the index row like this:


    - (void) addButtonPressed: (id) sender {

    UIButton *btnAdd = (UIButton *)sender;
    int indexRow = btnAdd.tag;

    }


    If it is, and now I have the index row that the button was pressed on, Im confused on how to change the label on that cell still. I may just not be understanding your example properly though. How do I declare my custom cell in the action so that I can do cell.quantityLabel.text = @"test"; for example?

    Also, how do I use the index row in order to change the text on the cell? Im not sure I understand this line correctly:


    UILabel *quantityLabel = [cell viewWithTag:kQuantityLabel];


    is it this line I use the index row with to change the text on that particular cell?

    Sorry for the probably simple questions, but i'm having trouble understanding this.

    Thanks, Si.
  • 3. Re: How to change text on a custom TableViewCell with a button on the cell
    AlmightySi Level 1 Level 1 (0 points)
    Still stuck on this! bump!
  • 4. Re: How to change text on a custom TableViewCell with a button on the cell
    RayNewbie Level 5 Level 5 (6,810 points)
    AlmightySi wrote:
    Is it fine to get the index row like this:

    - (void) addButtonPressed: (id) sender {
    UIButton *btnAdd = (UIButton *)sender;
    int indexRow = btnAdd.tag;
    }

    This wouldn't be my preference, Si. It doesn't include the possibility of multiple sections, and it could become problematic if you ever needed to allow the user to edit the table dynamically.
    Im confused on how to change the label on that cell still. I may just not be understanding your example properly though. How do I declare my custom cell in the action so that I can do cell.quantityLabel.text = @"test"; for example?

    I think my previous post was confusing because I was trying to cover too many possibilities. I.e., I wasn't sure whether you had made a custom cell in a nib by simply adding subviews, or whether you had made a custom subclass of UITableViewCell. Also I should have discussed the data store last time.

    Here's an example that might do more or less what you want. In this case, all of the cell's subviews are added in code. Adding them in a nib is probably best, but in the forum it's much easier to give you the code than the nib, ok?

    // RootViewController.h
    @interface RootViewController : UITableViewController {
    NSMutableArray *dataArray;
    }
    @property (nonatomic, retain) NSMutableArray *dataArray;
    @end

    // RootViewController.m
    #import "RootViewController.h"
    #define kTitleKey @"TitleKey" // dictionary key for cell title
    #define kQuantityKey @"QuantityKey" // dictionary key for cell quantity
    #define kTitleTag 100 // tag value for title label
    #define kQuantityTag 101 // tag value for quantity label

    @implementation RootViewController
    @synthesize dataArray;

    - (void)viewDidLoad {
    [super viewDidLoad];
    // make some data
    self.dataArray = [NSMutableArray arrayWithObjects:
    [NSMutableDictionary dictionaryWithObjectsAndKeys:@"Row 1", kTitleKey,
    [NSNumber numberWithInt:100], kQuantityKey, nil],
    [NSMutableDictionary dictionaryWithObjectsAndKeys:@"Row 2", kTitleKey,
    [NSNumber numberWithInt:100], kQuantityKey, nil],
    [NSMutableDictionary dictionaryWithObjectsAndKeys:@"Row 3", kTitleKey,
    [NSNumber numberWithInt:100], kQuantityKey, nil],
    [NSMutableDictionary dictionaryWithObjectsAndKeys:@"Row 4", kTitleKey,
    [NSNumber numberWithInt:100], kQuantityKey, nil],
    nil];
    }

    // helper method to update one cell and its data store
    - (void)resetQuantity:(int)cellTag plus:(BOOL)up {
    // obtain cell from tag
    UITableViewCell *cell = (UITableViewCell*)[self.tableView viewWithTag:cellTag];
    NSLog(@"%s: cell=%@", _func_, cell);
    // get index path of cell
    NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
    NSLog(@"%s: cell=%@ section=%d row=%d", _func_, cell, indexPath.section, indexPath.row);
    // update data store
    NSMutableDictionary *dict = [dataArray objectAtIndex:indexPath.row];
    int quantity = [[dict objectForKey:kQuantityKey] intValue];
    up ? quantity++ : quantity--;
    [dict removeObjectForKey:kQuantityKey];
    [dict setObject:[NSNumber numberWithInt:quantity] forKey:kQuantityKey];
    NSLog(@"%s: dict=%@", _func_, dict);
    // update quantity label on cell
    UILabel *label = (UILabel*)[cell viewWithTag:kQuantityTag];
    label.text = [NSString stringWithFormat:@"%d", quantity];
    }

    // action method for the plus buttons
    - (void)incrementCellQuantity:(id)sender {
    UIButton *button = sender;
    NSLog(@"%s: button.tag=%d", _func_, button.tag);
    [self resetQuantity:button.tag plus:YES];
    }

    // action method for the minus buttons
    - (void)decrementCellQuantity:(id)sender {
    UIButton *button = sender;
    NSLog(@"%s: button.tag=%d", _func_, button.tag);
    [self resetQuantity:button.tag plus:NO];
    }

    #pragma mark Table view methods
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
    }

    // Customize the number of rows in the table view.
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [dataArray count];
    }

    // helper method - add subviews to cell here instead of making a nib
    - (void)customizeCell:(UITableViewCell*)cell {
    // add title label
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 150, 21)];
    label.textAlignment = UITextAlignmentLeft;
    label.tag = kTitleTag;
    [cell.contentView addSubview:label];
    [label release];
    // add quantity label
    label = [[UILabel alloc] initWithFrame:CGRectMake(168, 11, 42, 21)];
    label.textAlignment = UITextAlignmentRight;
    label.tag = kQuantityTag;
    [cell.contentView addSubview:label];
    [label release];
    // add plus button
    UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    button.tag = cell.tag; // make the button tag the same as the cell tag
    button.frame = CGRectMake(222, 3, 40, 37);
    [button setTitle:@"+" forState:UIControlStateNormal];
    [button addTarget:self action:@selector(incrementCellQuantity:)
    forControlEvents:UIControlEventTouchUpInside];
    [cell.contentView addSubview:button];
    // add minus button
    button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    button.tag = cell.tag; // make the button tag the same as the cell tag
    button.frame = CGRectMake(270, 3, 40, 37);
    [button setTitle:@"-" forState:UIControlStateNormal];
    [button addTarget:self action:@selector(decrementCellQuantity:)
    forControlEvents:UIControlEventTouchUpInside];
    [cell.contentView addSubview:button];
    }

    // Customize the appearance of table view cells.
    - (UITableViewCell *)tableView:(UITableView *)tableView
    cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";
    static int CellTag = 1000;

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
    reuseIdentifier:CellIdentifier] autorelease];
    cell.tag = CellTag++; // assign unique tag to each cell when it's created
    [self customizeCell:cell];
    }
    // Configure the cell.
    NSDictionary *dict = [dataArray objectAtIndex:indexPath.row];
    // title
    UILabel *label = (UILabel*)[cell viewWithTag:kTitleTag];
    label.text = [dict objectForKey:kTitleKey];
    // quantity
    label = (UILabel*)[cell viewWithTag:kQuantityTag];
    int quantity = [[dict objectForKey:kQuantityKey] intValue];
    label.text = [NSString stringWithFormat:@"%d", quantity];
    return cell;
    }

    - (void)dealloc {
    [dataArray release];
    [super dealloc];
    }
    @end

    To build the example, just replace RootViewController.h and .m in the Navigation-based App template with the above. You won't need to open IB.

    - Ray
  • 5. Re: How to change text on a custom TableViewCell with a button on the cell
    AlmightySi Level 1 Level 1 (0 points)
    Thank you Ray, once again you've been helpful.

    Even though you've given me an example, it seems that im still having troubles converting this to work with my cells.I feel like I'm going to start pulling hair out soon.

    Would it be possible for me to contact your personally and send you my files for you to take a look at and see how you would do this for my table?

    Thanks, Si.
  • 6. Re: How to change text on a custom TableViewCell with a button on the cell
    RayNewbie Level 5 Level 5 (6,810 points)
    Ok, Si. Send the project folder to my aol account named RayNewbie. Also consider putting the folder up on a website so other's in the forum can see it. Meanwhile, I hope you build, run and study the example app. I tried to show you several ideas there which would apply to what you're trying to do, and once you understand how that code works I think you'll succeed in applying the same approach to your project. Sometimes we need to know when to quit stubbornly hacking away at a failed attempt, and take a fresh look. Once you have the project working, it's often easier to see why the first try was never going to work right. - Ray