Что не так с моим UITableView cellForRowAtIndex для одного выбора? - PullRequest
0 голосов
/ 24 января 2012

Ниже приведен код для UITableView, но когда я прокручиваю, он ведет себя странно (слишком раздражает) ... Эта проблема связана с reuseIdentifier .... но не знаю, как решить ..

- (UITableViewCell *)tableView:(UITableView *)tableView1 cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView1 dequeueReusableCellWithIdentifier:CellIdentifier];

    NSInteger imgTag = 1;
    NSInteger lblTag = 2;

    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;

        UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(2, 2, 52, 52)];
//        Image:[UIImage imageNamed:[self.glassType objectAtIndex:indexPath.row]]];
        imgView.tag = imgTag;
        [cell.contentView addSubview:imgView];
        [imgView release];

        UILabel *lblName = [[UILabel alloc] initWithFrame:CGRectMake(60, cell.frame.size.height/4, 200, 21)];
//        lblName.text = [self.glassName objectAtIndex:indexPath.row];
        lblName.tag = lblTag;
        [cell addSubview:lblName];
        [lblName release];
    }

    NSInteger imgIndex = 2;
    NSInteger lblIndex = 3;

    ((UIImageView *)[cell viewWithTag:imgTag]).image = [[self.glassType objectAtIndex:indexPath.row] objectAtIndex:imgIndex];
    ((UILabel *)[cell viewWithTag:lblTag]).text = [[self.glassName objectAtIndex:indexPath.row] objectAtIndex:lblIndex];

    return cell;
}

- (void)tableView:(UITableView *)tableView1 didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView1 cellForRowAtIndexPath:indexPath];
    cell.accessoryType = UITableViewCellAccessoryCheckmark;
}

Как сделать ячейку для строки по индексу, чтобы она оставалась постоянной даже при прокрутке ???Также как сделать одиночный выбор в UITableView ??

Ответы [ 3 ]

7 голосов
/ 24 января 2012

Ответ заключается в том, что вы не должны добавлять подпредставления в ячейки таблицы за пределами предложения «if (cell == nil) {...», иначе они будут добавляться снова и снова в одну и ту же ячейку, когда она возвращается б.

См. Мой ответ на этот вопрос для более подробного объяснения, включая код, как это исправить:

cellForRowAtIndexPath управление памятью

Вы также не можете сохранить состояние в ячейках таблицы, потому что, как только они прокручиваются за пределы экрана, они перерабатываются и снова появляются с другим индексом в вашей таблице. Вам необходимо настроить массив объектов модели для хранения состояния ячеек таблицы (например, каков должен быть их тип аксессуара). Более подробное объяснение можно найти в моем ответе на этот вопрос:

Цикл по UITableViewCells UITableView

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

Итак, поместите это в ваш tableView:cellForRowAtIndexPath: метод, прямо перед return cell;:

MyModelObject *object = [self.arrayOfModelObjects objectAtIndex:indexPath.row];
BOOL isChecked = object.checked;
cell.accessoryType = isChecked? UITableViewCellAccessoryCheckmark: UITableViewCellAccessoryNone;

А в вашем методе tableView: didSelectRowAtIndexPath: избавьтесь от текущей логики и замените ее на:

- (void)tableView:(UITableView *)tableView1 didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    for (int i = 0; i < [self.arrayOfModelObjects count]; i++)
    {
        MyModelObject *object = [self.arrayOfModelObjects objectAtIndex:i];
        object.checked = (i == indexPath.row); // only check the one we just tapped
    }

    //refresh table to update the accessory views for all rows
    [tableView1 reloadData];
}

Очевидно, замените arrayOfModelObjects вашей собственной реализацией модели. Вы можете просто использовать массив объектов NSNumber, содержащих bools, если вы не хотите создавать собственный класс для этой цели.

1 голос
/ 25 января 2012

Очередь переработки похожа на пул, в котором ранее созданные ячейки хранятся , прежде чем их можно использовать повторно.Например, когда вы прокручиваете вверх, в тот момент, когда ячейка исчезает сверху, она сохраняется в очереди и становится доступной для ячейки, которая появится внизу.Хорошо?

На самом деле количество реально созданных ячеек - это в точности максимальное число одновременных ячеек, которое вы можете отобразить в своей таблице (в большинстве случаев от 3 до 8).Другими словами, ваш if (cell == nil) код выполняется (более или менее от 3 до 8 раз) при первых reloadData для создания пула ячеек, необходимых вашей таблице.

Затем все, что вы делаете в ячейкесохраняется как есть и появляется снова, когда вы удаляете его с очереди .Теперь легко понять, что в вашем коде вы должны выполнять все строго зависящие от строки настройки вне блока if (cell == nil).Таким же образом, не добавляйте подпредставления вне блока if (cell == nil), вы можете представить тысячи подпредставлений, которые вы будете добавлять каждый раз при сбросе устаревшей ячейки!

Совет: если вам нужноПосле некоторой пользовательской очистки перед повторным использованием ячейки (например, чтобы установить пустое изображение), вы можете создать собственный класс UITableviewCell и реализовать метод prepareForReuse.

Понятно ли это?

0 голосов
/ 20 марта 2014

Всегда перезагружайте свой tableView в методе viewWillAppear вместо viewDidLoad.

  • (void) viewWillAppear: (BOOL) анимированный {

    [self.tableView reloadData];

    }

Это позволяет избежать наиболее неожиданных и раздражающих проблем. :)

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