views:

656

answers:

5

Hi everyone,

I need to create a custom settings view used within the app. The app is a mockup so it actually does have one already, it uses a UITableViewCellStyleValue1, but nothing is editable. So essentially what I would like to have is the same thing but with editable detailTextLabel (the label on the right hand side), what's the best way to do this?

+2  A: 

You can continue to use UITableViewCellStyleValue1. You'll need to create UITextField instances for each cell you want editable. Then you assign each UITextField to the appropriate cell's accessoryView property.

You can also match the color of the label text via:

yourTextField.textColor = cell.detailTextLabel.textColor;

You may need to fiddle with the frame property of the UITextField instances to get the alignment just right.

Danilo Campos
A: 

OK, so here's the code I have now, the textField is not displayed, I'm not sure why...

            - (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
 {
static NSString* reuseIdentifier = @"SettingsCell";

UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];

if ( !cell )
{ 
 cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:reuseIdentifier] autorelease];
 [cell setBackgroundColor:[UIColor baeDarkGrayColor]];


 UILabel* cellLabel = [cell textLabel];
 [cellLabel setTextColor:[UIColor whiteColor]];
 [cellLabel setBackgroundColor:[UIColor clearColor]];

 [cell setUserInteractionEnabled:YES];
 [cell setSelectionStyle:UITableViewCellSelectionStyleGray];
}

// Populate cell with corresponding data.
NSDictionary* tableSection = [_tableData objectAtIndex:indexPath.section];

// Set the label
UILabel* textLabel = [cell textLabel];
NSString* labelString = [[tableSection objectForKey:@"itemTitles"] objectAtIndex:indexPath.row];
[textLabel setText:labelString];

// Set the detail string
 // UILabel* detailLabel = [cell detailTextLabel];
 // NSString* detailLabelString = [[tableSection objectForKey:@"itemDetailStrings"]   objectAtIndex:indexPath.row];
 // [detailLabel setText:detailLabelString];

// Set the accessory view
BAESettingsTableCellAccessoryType accessoryType = [[[tableSection objectForKey:@"itemAccessories"] objectAtIndex:indexPath.row] integerValue];
switch ( accessoryType )
{
 case BAESettingsTableCellAccessoryDisclosureIndicator:
 {
  UIImageView* disclosureView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"AccessoryDisclosure.png"]];
  [cell setAccessoryView:disclosureView];
  [disclosureView release];
  break;
 }
 case BAESettingsTableCellAccessoryOnOffSwitch:
 {
  UISwitch* onOffSwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
  [onOffSwitch setOn:YES];
  [cell setAccessoryView:onOffSwitch];
  [onOffSwitch release];
  break;
 }
 case BAESettingsTableCellAccessoryNone:
  // default:
  // break;
 {
  UITextField* textField = [[UITextField alloc] init];
  NSString* detailLabelString = [[tableSection objectForKey:@"itemDetailStrings"] objectAtIndex:indexPath.row];
  textField.text = detailLabelString;
  textField.textColor = [UIColor whiteColor];
  [cell setAccessoryView:textField];
  [textField release];
  break;
 }

}

return cell;

}

Leonard
A: 

Your text field is not showing up because you never set the frame of the text field. You need to set the frame with a positive width and height. The height I would use is 43 (row height - 1px grey line buffer).

Ed Marty
A: 

Aha! OK, I got it! Now what I'm trying to do is dynamically define the width of the detail text field by looking at the width of the title label left in the cell. Most of the times I run this in the simulator the title label size is 0, but occasionally I get a result. This doesn't make any sense to me, I'm thinking maybe it's because cells are being reused or so? Do you guys have any ideas?

I added this piece of code after textLabel is set:

CGSize textLabelSize = [textLabel.text sizeWithFont:textLabel.font];

And then in the case block at the beginning I do:

CGRect cellFrame = [cell frame];

  float detailTextFieldWidth = cellFrame.size.width - ( textLabelSize.width + 50 );
  float detailTextFieldHeight = cellFrame.size.height - 1;

  NSLog(@"detail text field calculated frame width, height, %f, %f", detailTextFieldWidth, detailTextFieldHeight);


  CGRect frame = CGRectMake(cellFrame.origin.x, cellFrame.origin.y, detailTextFieldWidth, detailTextFieldHeight);


  UITextField* textField = [[UITextField alloc] initWithFrame:frame];
Leonard
A: 

I think that the easier way of doing this is to use the detailTextLabel to show the text and handle the show and hide of the text edit fields in the row selection code. I have this working with the following:


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    UITextField *tmpView = [self detailLabel:indexPath];
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    UILabel *detailLabel = [cell detailTextLabel];

    CGRect tmpFrame = [detailLabel frame]; // the existing frame 
    tmpFrame.size.width += 3; // space for the cursor
    tmpView.frame = tmpFrame;
    tmpView.textColor = detailLabel.textColor;
    cell.accessoryView = tmpView;
    detailLabel.text = nil;

    [tableView addSubview:tmpView];
    [tmpView becomeFirstResponder];

    [tableView setNeedsDisplay];
}

and the following on the de-select


- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    UITextField *tmpView = (UITextField *) cell.accessoryView;
    UILabel *label = [cell detailTextLabel];

    label.text = tmpView.text; 
    cell.accessoryView = nil;

    [tableView setNeedsDisplay];
}

The only other trick was to set the row selection highlighting in the cellForRowAtIndexPath to none...

  cell.selectionStyle = UITableViewCellSelectionStyleNone;
ridale