У меня есть таблица, в которой кнопка accessoriesView в ячейке заменяется значком пользовательского значка. Если интервал времени для пары настроек температуры включен, в строке ячейки отображается галочка, а также время, значение нагрева и охлаждения. Если время отключено, флажок отсутствует, а время, отображаемое в поле timefield.text, изменяется на состояние: «Отключено». Код работает нормально, когда я использую reloadData
. Однако, поскольку я обновляю только одну строку за раз, это слишком много для большой таблицы, которую я использую. Я пытаюсь использовать reloadRowsAtIndexPaths:
, но я получаю обновления экрана, которые влияют не только на ячейку, на которую было нажата, а на предыдущую ячейку, на которую была нажата кнопка. Я не использовал анимации (UITableViewRowAnimationNone
), но изменил это на затухающие анимации (UITableViewRowAnimationFade
), чтобы увидеть, что происходит. Разумеется, затухание происходит в нужной строке таблицы и в строке нежелательной таблицы. Кроме того, значение времени для текущей строки ячейки отображается в предыдущем поле строки ячейки. Как только я останусь с нажатием одной строки, никаких проблем с обновлениями нет, но как только я переключусь на другую строку, у меня есть две строки, затронувшие одно время. Это похоже на метод обновления, когда-то подхватывающий рывок.Странные обновления при использовании reloadRowsAtIndexPaths: в таблице
Я также попробовал брекетинг звонка 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];
}
Edit:
OK. Вот код, который вы запросили. Я надеюсь, что это помогает. Я буду рад опубликовать другие порции. К сожалению, в этом редакторе еще нет кода для форматирования.
// 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;
}
Можете ли вы также опубликовать реализацию cellForRowAtIndexPath? Я думаю, что это может быть связано с этим. –
OK, здесь. Это не самый красивый код, и я знаю, что эти addSubviews создают большую утечку памяти. – user1816236