开发者

UITableViewCell with UITextField losing the ability to select UITableView row?

I am almost done implementing a UITableViewCell with a UITextField in it. Rather then going through CGRectMake and UITableViewCell.contentView I have implemented it the simpler way:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"Cell"];
    [cell setSelectionStyle:UITableViewCellSelectionStyleBlue];
    amountField = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 190, 30)];
    amountField.placeholder = @"Enter amount";
    amountField.keyboardType = UIKeyboardTypeDecimalPad;
    amountField.textAlignment = UITextAlignmentRight;
    amountField.clearButtonMode = UITextFieldViewModeNever; 
    [amountField setDelegate:self];

    [[cell textLabel] setText:@"Amount"];
    [cell addSubview:amountField];
    return cell;
}

And then I also implemented the didSelectRow method, resigning the textField to allow showing the other fields input vie开发者_JAVA百科ws.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    ...
    [amountField resignFirstResponder];
    ...
}

This works smoothly, only thing is there are other rows in the table, when those others are selected the entire cell is selected and turns Blue, while the one with my UITextField doesn't, I mean the field is selected and I can enter text but the cell is not selected. I have tested it and figured out the problem is in the line:

[cell addSubview:amountField];

It seems that this breaks the selectable cell behavior, and even adding it to [cell contentView] doesn't fix this. Did I miss something?


If the text field has userInteractionEnabled set to YES, and it fills the entire cell, you can not get the cell to listen to touch. In order to get the cell to respond to touches, you need to set the userInteractionEnabled of the text field to NO.

Edit: And if you want to make the text field editable, when the cell is selected, add the following code in didSelectRowAtIndexPath: method,

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

    // get the reference to the text field
    [textField setUserInteractionEnabled:YES];
    [textField becomeFirstResponder];
}


You've not broken anything by adding a subview, instead the UITextField is capturing the touch ahead of the UITableViewCell. You can test this by tapping outside of the UITextField but within the bounds of the UITableViewCell and you'll see it does in fact still select as you would expect.

To get round this, you could subclass UITextField and add a UITableView property. Set the property when you instantiate the UITextField and add it to the cell.

amountField.tableView = tableView;

Then you'd need to override becomeFirstResponder in your subclass, and in the method get the row for the cell with the UITextField and then select it manually

- (BOOL)becomeFirstResponder
{
    // Get the rect of the UITextView in the UITableView's coordinate system
    CGRect position = [self convertRect:self.frame toView:self.tableView];
    // Ask the UITableView for all the rows in that rect, in this case it should be 1
    NSArray *indexPaths = [self.tableView indexPathsForRowsInRect:position];
    // Then manually select it
    [self.tableView selectRowAtIndexPath:[indexPaths objectAtIndex:0] animated:YES scrollPosition:UITableViewScrollPositionNone];
    return YES;
}


First Thing is you havent used reusable cells. The coding which you provided will cause a lot of memory.

Next thing is you can select the row by touching the area other than the textfield.

One solution for your ques is

In your textField Delegate

UITableViewCell *cell = (UITableViewCell *)[textField superView];
cell.selected=YES; //I think this will call the didSelectRowATIndex;

I am not sure this will work. But worth a try.


First of all you needed to use reuseIdentifier for cellForRowAtIndexPath, reason if you do not use reuseIdentifier is: when you scroll up and down, it will always allocate new cell and new textfields so you need to put cell==nil condition, so revised code is here:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
  static NSString *reuseIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
if (cell==nil) {
    cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier] autorelease];

     UITextField *amountField = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 190, 30)];
     amountField.placeholder = @"Enter amount";
     amountField.keyboardType = UIKeyboardTypeDecimalPad;
     amountField.textAlignment = UITextAlignmentRight;
     amountField.clearButtonMode = UITextFieldViewModeNever; 
     [amountField setDelegate:self];
     [cell.contentView addSubview:amountField];
}
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
[[cell textLabel] setText:@"Amount"];

return cell;
}

In didSelect delegate method you can do like this

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
  [prevField resignFirstResponder];
  UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
  UIView *view = [[cell.contentView subviews] lastObject];
  if([view isKindOfClass:[UITextField class]]{
     currentField = (UITextField*)view;
  }
  [currentField becomeFirstResponder];
  prevField = currentField;
}


inside the cell for row at index path add this line which is given in bold,

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"Cell"];
    [cell setSelectionStyle:UITableViewCellSelectionStyleBlue];

    amountField = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 190, 30)];
    amountField.placeholder = @"Enter amount";
    amountField.keyboardType = UIKeyboardTypeDecimalPad;
    amountField.textAlignment = UITextAlignmentRight;
    amountField.clearButtonMode = UITextFieldViewModeNever; 

    [amountField setDelegate:self];
    [[cell textLabel] setText:@"Amount"];

    **for (UIView *cellSubViews in cell.subviews) {
            cellSubViews.userInteractionEnabled = NO;
    }**

    [cell addSubview:amountField];
    return cell;
}

try this, it will work

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜