Неправильный indexPath.номер строки в повторно используемых ячейках в TableView

#ios #objective-c #uitableview

#iOS #objective-c #uitableview

Вопрос:

Как вы можете видеть в приведенном ниже коде, у меня есть tableView для times of racers. У первого гонщика (ов) золотой круг ( goldMedal изображение), у второго (ов) серебряный, а у третьего (ов) бронзовый, у всех остальных есть только medal изображение. Эти изображения представляют собой просто золотые / серебряные / бронзовые / черные круги. Я хочу поместить UILabel представление на это изображение медали с номером, который будет определять порядок следования участников в гонке, поэтому у гонщиков с лучшими (одинаковыми) временами будет goldMedal изображение с номером 1 на нем, у второго гонщика (ов) будет silverMedal изображение с номером 2 на нем и так далее. Проблема в том, что когда у меня слишком много участников в tableview и я прокручиваю вниз, у участников разные номера. Эти цифры меняются при прокрутке. Я не знаю, что с этим делать. Кто-нибудь может мне помочь?

Также я использовал helpIndex переменную для подсчета чисел для участников, которые равны 4. или хуже, но теперь есть indexPath.row и ни один из этих двух способов не сработал. Может ли кто-нибудь дать мне хотя бы свою точку зрения, как бы он решил эту проблему? Спасибо

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"SKSTableViewCell";
    SKSTableViewCell *sksTableViewCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    UILabel *numberLabel = [[UILabel alloc] initWithFrame:CGRectMake(sksTableViewCell.frame.origin.x 22.5, sksTableViewCell.frame.origin.y 20.5, 15, 15)];
    numberLabel.font = [UIFont systemFontOfSize:12];
    numberLabel.textColor = [UIColor whiteColor];
    numberLabel.textAlignment = NSTextAlignmentCenter;
    numberLabel.adjustsFontSizeToFitWidth = YES;

    if (!sksTableViewCell) {
        sksTableViewCell = [[SKSTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
        sksTableViewCell.backgroundColor = [UIColor clearColor];
        if ([[[[ArraySingleton sharedManager].sharedArray objectAtIndex:indexPath.row] times] count]) {
            sksTableViewCell.expandable = YES;
        } else {
            sksTableViewCell.expandable = NO;
        }
     }

     sksTableViewCell.imageView.image = [UIImage imageNamed:@"medal"];

     // Medals
     int golds = [[self.bestThreeRacersDictionary objectForKey:@"golds"] intValue];
     int silvers = [[self.bestThreeRacersDictionary objectForKey:@"silvers"] intValue];
     int bronzes = [[self.bestThreeRacersDictionary objectForKey:@"bronzes"] intValue];

     sksTableViewCell.textLabel.text = [NSString stringWithFormat:@"  %@",[[[ArraySingleton sharedManager].sharedArray objectAtIndex:indexPath.row] name]];
     numberLabel.text = [NSString stringWithFormat:@"%lu", [Racer shift:golds silvers:silvers bronzes:bronzes] indexPath.row];
     helpIndex  ;
     if (indexPath.row < golds) {
         sksTableViewCell.imageView.image = [UIImage imageNamed:@"goldMedal"];
         numberLabel.text = @"1";
         helpIndex--;
     } else if (indexPath.row < (golds silvers)) {
         sksTableViewCell.imageView.image = [UIImage imageNamed:@"silverMedal"];
         numberLabel.text = @"2";
         helpIndex--;
     } else if (indexPath.row < (golds silvers bronzes)) {
         sksTableViewCell.imageView.image = [UIImage imageNamed:@"bronzeMedal"];
         numberLabel.text = @"3";
         helpIndex--;
     }
     [sksTableViewCell addSubview:numberLabel];

     if ([[[[ArraySingleton sharedManager].sharedArray objectAtIndex:indexPath.row] times] count]) {
         sksTableViewCell.expandable = YES;
     } else {
         sksTableViewCell.expandable = NO;
     }
     sksTableViewCell.textLabel.text = [NSString stringWithFormat:@"%@", [[[ArraySingleton sharedManager].sharedArray objectAtIndex:indexPath.row] name]];

     return sksTableViewCell;
}
  

Комментарии:

1. Вы не извлекли уроков из своего предыдущего вопроса. Не продолжайте вызывать addSubview: ячейку снова и снова.

2. Добавление вложенных представлений в cellForRowAtIndexPath никогда не является хорошей идеей. Пусть ваш подкласс cell настроит представления либо программно в своем инициализаторе, либо через ячейку прототипа в раскадровке

Ответ №1:

 sksTableViewCell = [[SKSTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
  

Вы должны передать свой CellIdentifier здесь, иначе нет смысла проверять, существует ячейка или нет. UITableView всегда будет создаваться новая ячейка.

Пара моих заметок, которые могут вам помочь:

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

     -(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier  
      
  2. Вы можете создать четыре разных класса для каждого подкласса ячейки таблицы для Gold, Silver, Bronze и black и определить все в них и просто вызывать их на основе требований. Это уменьшит ваши накладные расходы, поскольку вы не будете выполнять эту работу снова и снова при прокрутке вверх и вниз. Кроме того, в будущем, если вам нужно будет выполнить более конкретную работу для каждой ячейки, это будет очень удобно для вас.

  3. Последнее, что имеет лестницу if else, также не очень хорошо. Таким образом, код может очень скоро выйти из строя и значительно снизить читаемость.

Ответ №2:

Вместо того, чтобы добавлять numberLabel снова и снова в cellForRowAtIndexPath, добавьте его в свою SKSTableViewCell:

 UILabel *numberLabel = [[UILabel alloc] initWithFrame:CGRectMake(sksTableViewCell.frame.origin.x 22.5, sksTableViewCell.frame.origin.y 20.5, 15, 15)];
numberLabel.font = [UIFont systemFontOfSize:12];
numberLabel.textColor = [UIColor whiteColor];
numberLabel.textAlignment = NSTextAlignmentCenter;
numberLabel.adjustsFontSizeToFitWidth = YES;
  

Проблема должна быть исправлена.