2010-10-31 2 views
0

У меня есть таблица, в которой кнопка 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; 

}

+0

Можете ли вы также опубликовать реализацию cellForRowAtIndexPath? Я думаю, что это может быть связано с этим. –

+0

OK, здесь. Это не самый красивый код, и я знаю, что эти addSubviews создают большую утечку памяти. – user1816236

ответ

1

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

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

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

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

Смежные вопросы