UITableViewCell与UITextField失去了选择UITableView行的能力?

时间:2011-07-05 08:36:08

标签: iphone objective-c ios cocoa-touch uitableview

我差不多完成了UITableViewCell,其中包含UITextField。而不是通过CGRectMakeUITableViewCell.contentView,我已经以更简单的方式实现了它:

- (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;
}

然后我还实现了didSelectRow方法,重新设置textField以允许显示其他字段的输入视图。

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

这很顺利,只有表中还有其他行,当选择其他行时,整个单元格被选中并变成蓝色,而我的UITextField的那个没有,我的意思是选择的字段和我可以输入文本,但不选择单元格。 我已经对它进行了测试,并发现问题在于:

[cell addSubview:amountField];

这似乎打破了可选择的单元格行为,甚至将其添加到[cell contentView]并不能解决这个问题。我错过了什么吗?

5 个答案:

答案 0 :(得分:42)

如果文本字段的 userInteractionEnabled 设置为 YES ,并且它填满整个单元格,则无法让单元格听取触摸。为了让单元格响应触摸,您需要将文本字段的 userInteractionEnabled 设置为 NO

修改如果您想使文本字段可编辑,请在选择单元格后,在 didSelectRowAtIndexPath:方法中添加以下代码,

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

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

答案 1 :(得分:6)

你没有通过添加子视图打破任何东西,而是UITextField在UITableViewCell之前捕获触摸。您可以通过点击UITextField外部但在UITableViewCell的范围内进行测试,你会发现它实际上仍然按照您的预期进行选择。

为了解决这个问题,你可以继承UITextField并添加一个UITableView属性。在实例化UITextField时设置属性并将其添加到单元格中。

amountField.tableView = tableView;

然后你需要在你的子类中覆盖 becomeFirstResponder ,并在方法中获取具有UITextField的单元格的行,然后手动选择它

- (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;
}

答案 2 :(得分:1)

首先,你没有使用可重复使用的细胞。您提供的编码会占用大量内存。

接下来,您可以通过触摸文本字段以外的区域来选择行。

问题的一个解决方案是

在textField委托

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

我不确定这是否有效。但值得一试。

答案 3 :(得分:1)

首先,你需要对cellForRowAtIndexPath使用reuseIdentifier,原因如果你不使用reuseIdentifier是:当你向上和向下滚动时,它总是会分配新的单元格和新的文本字段,所以你需要把cell == nil条件,修改后的代码在这里:

- (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;
}

在didSelect委托方法中你可以这样做

- (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;
}

答案 4 :(得分:1)

在索引路径的行的单元格内添加此行,以粗体显示,

- (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;
}

试试这个,它会起作用