UITableview-为单元格设置属性被重复使用的单元格搞砸了



我有一个UITableView,它充当窗体。它有大约20个单元格(具有静态内容,但具有动态单元格)。所以我有一个包含字段的数组,并将其加载到表视图中。在某个时候,用户将按下"提交"按钮,我需要在表视图的单元格中输入的所有文本字段值。因此,我为每个单元格中的每个文本字段创建了一个@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;

}

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

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

tableView:cellForRowAtIndexPath:中,您可以将正确的(实际的)数据传递到表单元格(这部分代码已经存在)。

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

UITextFieldTextDidChange通知

并保存对模型的更改。

也就是说,它看起来像这样。

@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;
                                                          }
                                                      }];
    }
}

为每个单元格提供了一个不同的标识符,如tableIdentifier=[string stringwithformat:"cellid%@",indexpath.row]。希望这能对您有所帮助。

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

可能的解决方案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

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

您可以将此函数添加到单元格对象中,因此当要重用单元格时,您必须检查数据并将其存储在其他地方。

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

最新更新