如何在 UITableViewCell 中提取 UITextField 的文本值?

Posted

技术标签:

【中文标题】如何在 UITableViewCell 中提取 UITextField 的文本值?【英文标题】:How to pull the text value for a UITextField inside a UITableViewCell? 【发布时间】:2011-02-28 19:42:28 【问题描述】:

我正在尝试使用 UITableView 设置基本排序。单元格的数量取决于通过segmentedControl 选择的字母,从而相应地将单元格重新加载到新产品中。

我遇到问题的部分是访问每种产品的数量。每个 UITableViewCell 都有一个产品图像和几个标签以及 UITextField 和一个操作按钮。这是我创建单元格的代码:

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

所有信息都直接在设备上呈现,但是当输入单个产品的数量时,quantityTextField 仅分配给屏幕上的最后一个单元格。我的问题是:如何将该指针移动到 UITable 中的先前单元格,以便能够获取给定产品的值?

【问题讨论】:

【参考方案1】:

我在上面的方法中看到您将productQuantityTextField(可能是该方法所在的类中的一个ivar)分配给单元格的文本字段。正如您所发现的,每次在屏幕上看到一个新单元格时,指针就会发生变化,并且无法取回其他指针。您可能注意到也可能没有注意到 productQuantityTextField 甚至不一定对应于页面中的最后一个文本字段。

在这种情况下,最好的做法是让您的班级在那里实现UITextFieldDelegate,并将您的班级分配为您创建的每个数量文本字段的代表。在textFieldDidEndEditing: 中,您将为特定文本字段确定合适的产品并将文本值保存到该特定产品。您还想更改上面的代码以读回该数量并将其设置为 quantityTextField 而不是始终为“0”,否则您会发现将一部分从屏幕上滚动然后重新打开会使它似乎忘记了数量.

【讨论】:

这个选项是我认为最适合这种情况的选项。使用委托是为了避免对所有内容进行子类化。我确实设置了我的类来实现 UITextFieldDelegate,而不是 textFieldDidEndEditing:,我实现了 textFieldShouldReturn:,这样我可以添加需要交互的使用实例方法,比如 UITextField 的 resignFirstResponder。我仍然想念一些我认为的东西; productQuantity 值显示在多个单元格上,由于某种原因,当您上下滚动时,产品代码会丢失。以前没有。 我知道 productCode 正在为该行保留,因为我可以上下滚动并仍将任何产品展开到它的详细视图。但是对于 textFields,productCode 的值会以一种奇怪的不一致方式表现。 搞定了,谢谢你的回答。我什至删除了添加按钮,因为可以使用 -(BOOL)textFieldShouldReturn:(UITextField *)textField 委托方法设置操作。【参考方案2】:

理想情况下,您会将其中的一些重构为自定义 UITableViewCell 类。从长远来看,它会更容易维护。

您不应依赖单元格或 UITextField 作为数据的后备存储。相反,让 UITextField 的委托在文本更改时更新您的数据模型。您的单元格可以根据需要缓存指向您的数据模型的指针。这在将文本字段放置在单元格中时尤其重要,因为您没有管理单元格的生命周期。也就是说,如果某个单元格滚动到屏幕外,您可能无法访问它,因为它已被释放或重新使用。

【讨论】:

以上是关于如何在 UITableViewCell 中提取 UITextField 的文本值?的主要内容,如果未能解决你的问题,请参考以下文章

如何借助 AutoLayout 在自定义 UITableviewCell 中添加自定义 UIView(xib)?

如何在其中使用UIStackView自定义UITableViewCell的大小

iOS 开发:如何在点击 UITableViewCell 时将其更改为可编辑的 UITextField?

为 UITableViewCell 上的特定按钮删除 UIButton 事件的链接

在 UITableViewCell 中使用渐变背景 [重复]

UITableViewCell 内的 UIScrollView - 水平滚动