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;

}

4 ответа

Решение

Вы можете извлекать данные только из видимых ячеек (невидимых ячеек не существует или они содержат неподходящие данные).

Есть несколько способов сделать это. Для вас лучшим решением будет делегировать (UITextFieldDelegate). Вы можете получить информацию об изменениях в UITextField, чтобы вы могли обновить свою модель данных.

В tableView:cellForRowAtIndexPath: Вы передаете правильные (фактические) данные в ячейку таблицы (эта часть кода у вас уже есть).

Предоставил каждой ячейке разные идентификаторы, например tableIdentifier = [string stringwithformat:"cellid%@",indexpath.row]. Надеюсь, что это поможет вам.

Допустим, у вас есть массив объектов, где каждый объект соответствует полю формы в вашем 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;
                                                          }
                                                      }];

    }
}

Я вижу 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

При подготовке к повторному использованию ячейки сохраните данные.

Вы можете добавить к объекту ячейки эту функцию, поэтому, когда ячейка собирается к повторному использованию, вы должны проверить данные и сохранить их в другом месте.

override func prepareForReuse(){
    // save data here an then....
    super.prepareForReuse()
}
Другие вопросы по тегам