UITableview - 为单元格设置 属性 与重复使用的单元格混淆

UITableview - Setting a property for cell is messed up with reused cells

我有一个用作表单的 UITableView。 它有大约 20 个单元格(具有静态内容但动态单元格)。 所以我有一个包含字段的数组并将其加载到 table 视图中。 有时用户会按下 "Submit" 按钮,我需要在 table 视图的单元格中输入的所有文本字段值。 所以我为每个单元格中的每个文本字段创建了一个 @property 并在 cellForRowAtIndexPath:.

中分配它
 if (indexPath.row==RPCVehicleType || indexPath.row==RPCExcess || indexPath.row==RPCDrivers){

    static NSString *tableIdentifier = @"TextFieldArrowCell";

    TextFieldArrowCell *cell = (TextFieldArrowCell*)[tableView dequeueReusableCellWithIdentifier:tableIdentifier];

    if (cell == nil) {
        cell = [[TextFieldArrowCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:tableIdentifier];
    }

    switch (indexPath.row) {
        case RPCVehicleType:
            self.typeOfVehicleTextfield = cell.valueField;
            break;
        case RPCExcess:
            self.excessTextfield = cell.valueField;
            break;
        case RPCDrivers:
            self.driversTextfield = cell.valueField;
            break;
        default:
            break;
    }

    return cell;

这段代码的问题是,当我滚动到底部时,单元格被重复使用并且属性被弄乱了。因此,当我第一次执行 [self.excessTextField setText:@"123"] 时没问题,但在滚动并再次执行后,我可以看到相同类型单元格的其他文本字段更改为该值。 有解决此问题的解决方法吗?

更新: 尝试了这种方法,结果相同:

-(UITextField*)getTextFieldForRow:(NSInteger)row{

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0];
TextFieldArrowCell *cell = [self.tableV cellForRowAtIndexPath:indexPath];

return cell.valueField;

}

我可以看到 2 种可能的方法来解决您的问题。

可能的解1

使用您自己的单元格而不重复使用它们,在这种情况下,您将始终可以访问存储在文本字段中的信息。

这是 Swift 中的示例代码,可轻松翻译为 Objective-c

var myCellArray:[TextFieldArrowCell?] = Array.init(count: 3, repeatedValue: nil)

func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!  {

        if (myCellsArray[indexPath.row] == nil) {
            myCellsArray[indexPath.row] = UITableViewCell(style: .Default, reuseIdentifier: "TextFieldArrowCell") as! TextFieldArrowCell

        //Config the cell

        }
        return myCellsArray[indexPath.row]
    }

最后,在保存按钮中,查询你的数组,并读取文本字段的数据。

可能的解法2

准备重用单元格时,存储数据。

你可以给你的cell对象添加这个功能,所以当cell要被重用的时候,你必须检查数据并存储在其他地方。

override func prepareForReuse(){
    // save data here an then....
    super.prepareForReuse()
}

假设您有一个对象数组,其中每个对象对应于您的 tableView 中的表单字段。当您出列一个单元格时,您需要将相应的对象分配给您的 UITableViewCell 子类。 现在让你的 UITableViewCell 子类成为

的接收者

UITextFieldTextDidChangeNotification

并保存对模型的更改。

即它看起来像这样。

@interface MyObject: NSObject 
@property (strong, nonatomic) NSString *someValue;
@end

// Dequeue your cell..
 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

   MyCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyIdentifier"];
   // Assign an object to your cell
   cell.object = arrayOfObjects[indexPath.row];
   return cell;
}

// Register cell as an observer

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {

    if (self = [super initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:reuseIdentifier]) {
    // Your init code
    [[NSNotificationCenter defaultCenter] addObserverForName:UITextFieldTextDidChangeNotification
                                                object:self.textField
                                                       queue:[NSOperationQueue mainQueue]
                                                      usingBlock:^(NSNotification * _Nonnull note) {

                                                          if ([note.object isEqual:self.textField]) {
                                                              self.object.value = self.textField.text;
                                                          }
                                                      }];

    }
}

为每个单元格提供不同的标识符,如表标识符 = [字符串字符串格式:"cellid%@",indexpath.row]。希望对您有所帮助。

您只能从可见单元格中检索数据(不可见单元格不存在或它们包含不适当的数据)。

有几种方法可以做到这一点。 对于您来说,最好的解决方案是委托 (UITextFieldDelegate)。 您可以获得有关 UITextField 更改的信息,因此您可以更新您的数据模型。

tableView:cellForRowAtIndexPath: 中,您将正确的(实际)数据传递给 table 单元格(这部分代码您已经有了)。