Странные обновления при использовании reloadRowsAtIndexPaths: в таблице - PullRequest
0 голосов
/ 31 октября 2010

У меня есть таблица, в которой кнопка accessoryView в ячейке заменена значком пользовательской галочки.Если интервал времени для пары настроек температуры включен, в строке ячейки отображается галочка, а также время, значение нагрева и охлаждения.Если время отключено, галочка отсутствует, а время, отображаемое в timefield.text, изменяется на «Отключено».Код работает нормально, когда я использую reloadData.Однако, поскольку я обновляю только одну строку за раз, для большой таблицы, которую я использую, это излишне.Я пытаюсь использовать reloadRowsAtIndexPaths:, но я получаю обновления экрана, которые влияют не только на ячейку, на которой была нажата кнопка, но и на предыдущую ячейку, на которой была нажата кнопка.Я не использовал никакой анимации (UITableViewRowAnimationNone), но изменил ее на анимацию затухания (UITableViewRowAnimationFade), чтобы увидеть, что происходит.Конечно же, замирания происходят в нужной строке таблицы и в нежелательной строке таблицы.Кроме того, значение времени для текущей строки ячейки появляется в поле времени предыдущей строки ячейки.Как только я продолжаю нажимать на одну строку, с обновлениями проблем не возникает, но как только я переключаюсь на другую строку, обе строки затрагивают один раз.Это похоже на то, что метод обновления берет что-то вздор.

Я также пытался заключить в скобки вызов reloadRowsAtIndexPaths: с вызовами beginUpdates и endUpdates, и ничего не меняется.

ПонятноЯ не понимаю чего-то фундаментального здесь.Что я делаю неправильно?Вот этот метод:

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

  UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
  UIButton *button = (UIButton *)cell.accessoryView;

  BOOL checked;

  if (intervalDisabled[((indexPath.section * 4) + indexPath.row)] == NO) {
    checked = YES;
    intervalDisabled[((indexPath.section * 4) + indexPath.row)] = YES;
  } else {
    checked = NO;
    intervalDisabled[((indexPath.section * 4) + indexPath.row)] = NO;
  }

  UIImage *newImage = (checked) ? [UIImage imageNamed:@"unchecked.png"] : [UIImage imageNamed:@"checked.png"];
  [button setBackgroundImage:newImage forState:UIControlStateNormal];

  timeField.text = [NSString stringWithFormat:@"%@", [self.dateFormatter stringFromDate:[timeOfDays objectAtIndex:((indexPath.section * 4) + indexPath.row)]]];

  //[self.tableView reloadData]; <-- This works fine

  NSArray *rowArray = [NSArray arrayWithObject:indexPath];

  [self.tableView reloadRowsAtIndexPaths:rowArray withRowAnimation:UITableViewRowAnimationFade];
}

Редактировать:

ОК.Вот код, который вы просили.Я надеюсь, что это помогает.Я буду рад опубликовать другие порции.Извините, я еще не знаком с форматированием кода в этом редакторе.

// Customized cell for setpoints

- (UITableViewCell *) setPointsCell: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath {NSString * TemperatureSymbol;

static NSString *kCustomCellID = @"setPointsCellID";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCustomCellID];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:kCustomCellID] autorelease];
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    cell.selectionStyle = UITableViewCellSelectionStyleBlue;
}

// Set up the cell. 
NSDictionary *dictionary = [listOfRows3 objectAtIndex:indexPath.section];
NSArray *array = [dictionary objectForKey:@"Content"];
NSString *cellValue = [array objectAtIndex:indexPath.row];

//Set properties of label and add its text
cell.textLabel.font = [UIFont systemFontOfSize:[UIFont labelFontSize]];
cell.textLabel.text = cellValue;

// Add time field
timeField = [[UITextField alloc] init];
timeField.tag = (indexPath.section * 100) + (indexPath.row * 10) + TIME_FIELD;
CGRect frame = CGRectMake(80.0, 6.0, 90.0, 31.0);
timeField.frame = frame;
timeField.borderStyle = UITextBorderStyleRoundedRect;
timeField.font = [UIFont systemFontOfSize:[UIFont labelFontSize]];
//  timeField.backgroundColor = [UIColor clearColor];

timeField.textAlignment = UITextAlignmentRight;

// Check and handle situation where time interval is disabled
BOOL rowHasCheck;

if (intervalDisabled[((indexPath.section * 4) + indexPath.row)] == NO) {
    rowHasCheck = YES;
    timeField.text = [NSString stringWithFormat:@"%@", [self.dateFormatter stringFromDate:[timeOfDays objectAtIndex:((indexPath.section * 4) + indexPath.row)]]];
} else {
    rowHasCheck = NO;
    timeField.text = @"Disabled";
}

UIImage *image = (rowHasCheck) ? [UIImage imageNamed:@"checked.png"] : [UIImage imageNamed:@"unchecked.png"];

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
CGRect bFrame = CGRectMake(0.0, 0.0, image.size.width, image.size.height);
button.frame = bFrame;  // match the button's size with the image size

[button setBackgroundImage:image forState:UIControlStateNormal];

// set the button's target to this table view controller so we can interpret touch events and map that to a NSIndexSet
[button addTarget:self action:@selector(checkButtonTapped:event:) forControlEvents:UIControlEventTouchUpInside];
button.backgroundColor = [UIColor clearColor];
cell.accessoryView = button;


// Override default keyboard handler so we can use a picker instead
timeField.delegate = self;

[cell.contentView addSubview:timeField];

// Set up termperature (F or C) to display
if (temperatureScale == FAHRENHEIT) {
    temperatureSymbol = @"F";
} else {
    temperatureSymbol = @"C";
}

// Add heating setpoint field
UITextField *heatingSetPointField = [[UITextField alloc] init];
heatingSetPointField.tag = (indexPath.section * 100) + (indexPath.row * 10) + HEATING_FIELD;

frame = CGRectMake(180.0, 6.0, 52.0, 31.0);
heatingSetPointField.frame = frame;
heatingSetPointField.borderStyle = UITextBorderStyleBezel;
heatingSetPointField.backgroundColor = [UIColor colorWithRed:1.0 green:0.2 blue:0.2 alpha:1.0];
heatingSetPointField.font = [UIFont systemFontOfSize:[UIFont labelFontSize]];
heatingSetPointField.textAlignment = UITextAlignmentRight;

heatingSetPointField.text = [NSString stringWithFormat:@"%i %@", hSetpoints[((indexPath.section * 4) + indexPath.row)], temperatureSymbol];

// Override default delegate handler
heatingSetPointField.delegate = self;

[cell.contentView addSubview:heatingSetPointField];

// Add cooling setpoint field
UITextField *coolingSetPointField = [[UITextField alloc] init];
coolingSetPointField.tag = (indexPath.section * 100) + (indexPath.row * 10) + COOLING_FIELD;
frame = CGRectMake(240.0, 6.0, 52.0, 31.0);
coolingSetPointField.frame = frame;
coolingSetPointField.borderStyle = UITextBorderStyleBezel;
coolingSetPointField.font = [UIFont systemFontOfSize:[UIFont labelFontSize]];
coolingSetPointField.backgroundColor = [UIColor colorWithRed:0.4 green:0.4 blue:1.0 alpha:1.0];
coolingSetPointField.textAlignment = UITextAlignmentRight;
coolingSetPointField.text = [NSString stringWithFormat:@"%i %@", cSetpoints[((indexPath.section * 4) + indexPath.row)], temperatureSymbol];

// Override default delegate handler
coolingSetPointField.delegate = self;

[cell.contentView addSubview:coolingSetPointField];

[timeField release];
[heatingSetPointField release];
[coolingSetPointField release]; 

return cell;

}

1 Ответ

1 голос
/ 01 ноября 2010

Основная проблема в том, что вы, похоже, используете одну ссылку timeField во всех ячейках. Как минимум, timeField должен быть создан отдельно в каждой ячейке (как, например, heatingSetPointField), а затем извлечь его из ячейки позже, используя его тег.

Существует много других проблем (например, текстовые поля будут добавляться несколько раз в каждую ячейку при повторном использовании ячейки).

Я думаю, что reloadData "работает", потому что вы не пробовали прокручивать представление таблицы вверх / вниз и видеть неправильные данные в ячейках, когда они возвращаются в представление.

Возможно, вы захотите прочитать Руководство по программированию табличного представления (особенно раздел «Настройка ячеек») и начать с более простой ячейки табличного представления и добавлять один слой сложности за раз, пока не достигнете своей цели.

...