iOS: как правильно получить доступ к пользовательским меткам на contentView UITableViewCell? - PullRequest
1 голос
/ 26 марта 2012

У меня есть UITableView с каждой ячейкой, разбитой на несколько разделов с разными метками в каждом разделе. Таблица заполняется NSArray NSDictionaries, который содержит все данные, которые заполняют метки ячейки. Эта часть UITableView прекрасно работает.

Проблема возникает, когда я изменяю некоторые значения в одном из NSDictionaries, а затем перезагружаю таблицу с обновленным NSArray. Обычно, когда я вызываю [myTableView reloadData];, ничего не обновляется, хотя (посредством отладки) я вижу, что обновленные данные обрабатываются. Но если я изменю стандарт: if (cell == nil) { на if (1) {, в методе cellForRowAtIndexPath, то он прекрасно работает. Я понимаю, почему if(1) { работает, но я не понимаю, почему я не могу повторно использовать ячейки и просто изменить текст метки.

Почему if (cell == nil) не работает? Это огромный расход ресурсов для повторной инициализации каждой ячейки?

КОД:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

static NSString *cellIdentifier = @"myCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: cellIdentifier];

if (/*cell == nil*/1) {
    // Initialize Custom Cell
    cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];

    //// Background View
    cellBackgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 622, 43)];
    [cellBackgroundView setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"Images/Library/phase_table_cell.png"]]];

    //// Name Label
    nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 250, 18)];
    [nameLabel setBackgroundColor:[UIColor clearColor]];
    [cellBackgroundView addSubview:nameLabel];

    //// Percent Complete Label
    percentCompleteLabel = [[UILabel alloc] initWithFrame:CGRectMake(300, 10, 30, 18)];
    [percentCompleteLabel setBackgroundColor:[UIColor clearColor]];
    [percentCompleteLabel setTextAlignment:UITextAlignmentCenter];
    [cellBackgroundView addSubview:percentCompleteLabel];

    //// Overall Status Label
    overallStatusLabel = [[UILabel alloc] initWithFrame:CGRectMake(352, 7, 63, 30)];
    [overallStatusLabel setBackgroundColor:[UIColor clearColor]];
    [overallStatusLabel setFont:[UIFont boldSystemFontOfSize:12.0]];
    [overallStatusLabel setLineBreakMode:UILineBreakModeWordWrap];
    [overallStatusLabel setNumberOfLines:2];
    [overallStatusLabel setTextAlignment:UITextAlignmentCenter];
    [cellBackgroundView addSubview:overallStatusLabel];

    //// Finish Date Label
    finishDateLabel = [[UILabel alloc] initWithFrame:CGRectMake(425, 10, 55, 18)];
    [finishDateLabel setBackgroundColor:[UIColor clearColor]];
    [finishDateLabel setTextAlignment:UITextAlignmentCenter];
    [finishDateLabel setFont:[UIFont systemFontOfSize:12.0]];
    [cellBackgroundView addSubview:finishDateLabel];

    //// Overall Weight Label
    overallWeightLabel = [[UILabel alloc] initWithFrame:CGRectMake(505, 10, 30, 18)];
    [overallWeightLabel setBackgroundColor:[UIColor clearColor]];
    [overallWeightLabel setTextAlignment:UITextAlignmentCenter];
    [cellBackgroundView addSubview:overallWeightLabel];

    //// Green Risk View
    greenRiskView = [[UIView alloc] initWithFrame:CGRectMake(557, 4, 61, 10)];
    [greenRiskView setBackgroundColor:[UIColor greenColor]];
    [greenRiskView setHidden:YES];
    [cellBackgroundView addSubview:greenRiskView];

    //// Yellow Risk View
    yellowRiskView = [[UIView alloc] initWithFrame:CGRectMake(557, 17, 61, 10)];
    [yellowRiskView setBackgroundColor:[UIColor yellowColor]];
    [yellowRiskView setHidden:YES];
    [cellBackgroundView addSubview:yellowRiskView];

    //// Red Risk View
    redRiskView = [[UIView alloc] initWithFrame:CGRectMake(557, 30, 61, 10)];
    [redRiskView setBackgroundColor:[UIColor redColor]];
    [redRiskView setHidden:YES];
    [cellBackgroundView addSubview:redRiskView];

    [cell.contentView addSubview:cellBackgroundView];
}

// Get Current Dictionary
NSDictionary *dictForIndexPath = [self.phaseArray objectAtIndex:[indexPath row]];
// Set Elements
[nameLabel setText:[dictForIndexPath objectForKey:@"name"]];
[percentCompleteLabel setText:[dictForIndexPath objectForKey:@"percentComplete"]];
[overallStatusLabel setText:[dictForIndexPath objectForKey:@"overallStatus"]];
[overallWeightLabel setText:[[NSNumber numberWithInt:[[dictForIndexPath objectForKey:@"overallWeight"] intValue]] stringValue]];
//// Create Finish Date String
NSString *finishDateString = [NSString stringWithFormat:@"%@/%@/%@", [dictForIndexPath objectForKey:@"finishDay"], [dictForIndexPath objectForKey:@"finishMonth"], [dictForIndexPath objectForKey:@"finishYear"]];
[finishDateLabel setText:finishDateString];
//// Pick Risk View
NSString *riskColor = [dictForIndexPath objectForKey:@"riskColor"];
if ([riskColor isEqualToString:@"Green"]) {
    [greenRiskView setHidden:NO];
    [yellowRiskView setHidden:YES];
    [redRiskView setHidden:YES];
} else if ([riskColor isEqualToString:@"Yellow"]) {
    [greenRiskView setHidden:YES];
    [yellowRiskView setHidden:NO];
    [redRiskView setHidden:YES];
} else {
    [greenRiskView setHidden:YES];
    [yellowRiskView setHidden:YES];
    [redRiskView setHidden:NO];
}

return cell;
}

1 Ответ

3 голосов
/ 26 марта 2012

Возможно, вы присваиваете значение в блоке if(cell==nil)? Только инициализация должна происходить внутри этого блока. Переместите остальное из этого. (Отправьте полный код cellForRow, если вам нужна дополнительная помощь)

// редактировать: теперь, после того, как вы опубликовали свой код, я вижу вашу проблему:

вы храните все свои метки и представления в переменных-членах ... но, конечно, это происходит только при выполнении блока if(cell != nil). После этого вы всегда получаете доступ к одной и той же ячейке (которая была назначена последней). Итак, вы обновляете хотя бы одну ячейку;)

Чтобы решить вашу проблему, работайте, например, с тегами, чтобы получить ваши соответствующие представления обратно из клетки. Я покажу это для вашего backgroundView, но вы должны сделать это для всех ваших представлений (INSTEAD переменных-членов. Удалите их.)

static NSString *cellIdentifier = @"myCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: cellIdentifier];

if (cell == nil) {
  //// Background View
  UIView* cellBackgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 622, 43)];
  cellBackgroundView.tag = 1;
  [cellBackgroundView setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"Images/Library/phase_table_cell.png"]]];
}

// get the backgroundview from the current cell
UIView* backgroundView = [cell.contentView viewWithTag: 1];

и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...