Reputation: 6468
I am trying to set up a basic ordering using a UITableView. The number of cells varies depending on a letter selected through a segmentedControl which in turn reloads the cells to the new products accordingly.
The portion I am having the problem with is accessing the quantity for each product. Each UITableViewCell has an image for the product and a couple of labels along with the UITextField and an action button. Here is the code for my cell creation:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
UIButton *productButton = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *productButtonImage = [[[UIImage alloc] initWithData:[NSData dataWithContentsOfFile:[[productList objectAtIndex:indexPath.row] valueForKey:@"product_small_image_filepath"] options:NSDataReadingMapped error:nil]] autorelease];
productButton.frame = CGRectMake(9.0, 3.0, 48.0, 84.0);
[productButton setBackgroundImage:productButtonImage forState:UIControlStateNormal];
[productButton setTag:indexPath.row];
[productButton addTarget:self action:@selector(loadProductDetailAtIndexPath:) forControlEvents:UIControlEventTouchDown];
UILabel *productCodeLabel = [[[UILabel alloc] initWithFrame:CGRectMake(67.0, 0.0, 300.0, 34.0)] autorelease];
productCodeLabel.tag = 100;
[productCodeLabel setBackgroundColor:[UIColor clearColor]];
[productCodeLabel setTextColor:[UIColor whiteColor]];
UILabel *productNameLabel = [[[UILabel alloc] initWithFrame:CGRectMake(67.0, 34.0, 300.0, 23.0)] autorelease];
productNameLabel.tag = 101;
[productNameLabel setBackgroundColor:[UIColor clearColor]];
[productNameLabel setTextColor:[UIColor lightGrayColor]];
UILabel *productSizeLabel = [[[UILabel alloc] initWithFrame:CGRectMake(67.0, 57.0, 300.0, 23.0)] autorelease];
productSizeLabel.tag = 102;
[productSizeLabel setBackgroundColor:[UIColor clearColor]];
[productSizeLabel setTextColor:[UIColor grayColor]];
UILabel *typeQuantityLabel = [[[UILabel alloc] initWithFrame:CGRectMake(380.0, 35.0, 100.0, 30.0)] autorelease];
typeQuantityLabel.tag = 103;
[typeQuantityLabel setBackgroundColor:[UIColor clearColor]];
[typeQuantityLabel setTextColor:[UIColor whiteColor]];
UITextField *numberOfItemsTextField = [[[UITextField alloc] initWithFrame:CGRectMake(480.0, 35.0, 150.0, 30.0)] autorelease];
numberOfItemsTextField.tag = 104;
[numberOfItemsTextField setKeyboardType:UIKeyboardTypeNumberPad];
[numberOfItemsTextField setReturnKeyType:UIReturnKeyDone];
[numberOfItemsTextField setBackgroundColor:[UIColor clearColor]];
[numberOfItemsTextField setBorderStyle:UITextBorderStyleRoundedRect];
[numberOfItemsTextField setTextAlignment:UITextAlignmentRight];
UIButton *productAddButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
productAddButton.frame = CGRectMake(650.0, 35.0, 70.0, 30.0);
productAddButton.tag = indexPath.row;
[productAddButton setBackgroundColor:[UIColor clearColor]];
[productAddButton setTitle:@"ADD" forState:UIControlStateNormal];
[productAddButton setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
[productAddButton addTarget:self action:@selector(addItemToOrderedItemsMutableArray:) forControlEvents:UIControlEventTouchDown];
[cell addSubview:productButton];
[cell addSubview:productCodeLabel];
[cell addSubview:productNameLabel];
[cell addSubview:productSizeLabel];
[cell addSubview:typeQuantityLabel];
[cell addSubview:numberOfItemsTextField];
[cell addSubview:productAddButton];
UIView *v = [[[UIView alloc] init] autorelease];
v.backgroundColor = [[UIColor clearColor] colorWithAlphaComponent:0.5];
[cell setSelectedBackgroundView:v];
}
// Configure the cell...
UIButton *productButton = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *productButtonImage = [[[UIImage alloc] initWithData:[NSData dataWithContentsOfFile:[[productList objectAtIndex:indexPath.row] valueForKey:@"product_small_image_filepath"] options:NSDataReadingMapped error:nil]] autorelease];
productButton.frame = CGRectMake(9.0, 3.0, 48.0, 84.0);
[productButton setBackgroundImage:productButtonImage forState:UIControlStateNormal];
[productButton setTag:indexPath.row];
[productButton addTarget:self action:@selector(loadProductDetailAtIndexPath:) forControlEvents:UIControlEventTouchDown];
[cell addSubview:productButton];
UILabel *productCodeLabel = (UILabel *)[cell viewWithTag:100];
[productCodeLabel setText:[[productList objectAtIndex:indexPath.row] valueForKey:@"product_code"]];
self.productCode = [[productList objectAtIndex:indexPath.row] valueForKey:@"product_code"];
UILabel *productNameLabel = (UILabel *)[cell viewWithTag:101];
[productNameLabel setText:[[productList objectAtIndex:indexPath.row] valueForKey:@"product_name"]];
UILabel *productSizeLabel = (UILabel *)[cell viewWithTag:102];
[productSizeLabel setText:[[productList objectAtIndex:indexPath.row] valueForKey:@"product_size"]];
UILabel *typeQuantityLabel = (UILabel *)[cell viewWithTag:103];
[typeQuantityLabel setText:@"QUANTITY"];
UITextField *quantityTextField = (UITextField *)[cell viewWithTag:104];
[quantityTextField setText:@"0"];
productQuantityTextField = quantityTextField;
return cell;
}
All the information renders right on the device, but when it comes down to enter the quantity for an individual product, quantityTextField is only assigned to the last Cell on the screen. My question is: How can I move that pointer to the previous cells in the UITable in order to be able to obtain the value for a given product?
Upvotes: 1
Views: 807
Reputation: 39512
Ideally you'd refactor some of this into a custom UITableViewCell class. In the long run it will be a lot easier to maintain.
You shouldn't depend on your cell or the UITextField to be the backing store for your data. Rather, have the delegate for the UITextField update your datamodel as the text is changed. Your cell can cache a pointer to your datamodel as required. This is especially important when placing textfields in cells because you aren't managing the lifetime of the cell. That is, you may not be able to access a given cell if it is scrolled offscreen, because it was deallocated or re-used.
Upvotes: 1
Reputation: 94794
I see in the method above you assign productQuantityTextField
, which is presumably an ivar in the class this method is in, to the text field from the cell. As you've found, each time a new cell becomes visible on screen that pointer gets changed, and there is no way to get back the other pointers. You may or may not have noticed that productQuantityTextField
doesn't necessarily even correspond to the last text field in the page.
The best thing to do in this case would be to have your class there implement UITextFieldDelegate
, and assign your class as the delegate for each quantity text field you create. In textFieldDidEndEditing:
, you would determine the appropriate product for the particular text field and save the text value to that particular product. You'd also want to change your code above to read back that quantity and set it to quantityTextField instead of "0" always, otherwise you'll find that scrolling a part off the screen and then back on makes it seem to forget the quantity.
Upvotes: 2