Аксессуарная галочка на uitableviewcell не отображается в некоторых случаях

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

В таблице около 100-200 записей, и у меня есть дополнительный вид, который представляет собой галочку, которая при выборе ячейки отмечает ячейку, а затем снова загружает основной вид.

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

Он имеет тенденцию работать примерно в верхних 30/40% таблицы, но все, что ниже галочки, не будет видно ... то есть, если я не буду ходить вперед и назад, становясь все глубже и глубже каждый раз, тогда иногда я могу получить галочку. в более глубокой части таблицы. Кто-нибудь знает, почему это происходит?

Случалось ли с кем-нибудь что-то в этом роде раньше?

При дальнейшем расследовании я думаю, что внутри этого метода что-то идет не так.

Прежде всего, в подпредставлении, когда пользователь выбирает ячейку, этот метод вызывается

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

 // Navigation logic may go here. Create and push another view controller.
    [self.navigationController popViewControllerAnimated:YES]; //pops current view from the navigatoin stack

    //accesses selected cells content
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    // now you can use cell.textLabel.text

    //This if statment is based off which cell was selected in the parent view so that it knows which cell to pass the data back to
    if (parentViewSelectedIndexPath.section == 0) {
        if (parentViewSelectedIndexPath.row == 0) {
            manufactureCellTextLabel = cell.textLabel.text; //passing label text over to NSString for use with delegate (check "viewwilldissapear")
            [[self delegate] setManufactureSearchFields:manufactureCellTextLabel withIndexPath:indexPath]; //This is where I pass the value back to the mainview
        }
// a few more If statements for the other methods I can pass data too.


//--- this if block allows only one cell selection at a time
    if (oldCheckedData == nil) { // No selection made yet
        oldCheckedData = indexPath;
        [cell setAccessoryType:UITableViewCellAccessoryCheckmark];

    }
    else {
        UITableViewCell *formerSelectedcell = [tableView cellForRowAtIndexPath:oldCheckedData]; // finding the already selected cell
        [formerSelectedcell setAccessoryType:UITableViewCellAccessoryNone];

        [cell setAccessoryType:UITableViewCellAccessoryCheckmark]; // 'select' the new cell
        oldCheckedData = indexPath;
    }   
}

Это передает путь индекса методу основного представления...

   - (void) setManufactureSearchFields:(NSString *)cellLabeltext withIndexPath:(NSIndexPath *)myIndexPath
    {
        manufactureSearchObjectString = cellLabeltext;
        manufactureResultIndexPath = myIndexPath;
        [self.tableView reloadData]; //reloads the tabels so you can see the value.
    }

// Который затем устанавливает factoryResultIndexPath, который используется в следующем методе, чтобы передать его обратно в подпредставление

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Navigation logic may go here. Create and push another view controller.
    //--- Idendify selected indexPath (section/row)
    if (indexPath.section == 0) {
        //--- Get the subview ready for use
        VehicleResultViewController *vehicleResultViewController = [[VehicleResultViewController alloc] initWithNibName:@"VehicleResultViewController" bundle:nil];
        // ...
        //--- Sets the back button for the new view that loads
        self.navigationItem.backBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:@"Back" style: UIBarButtonItemStyleBordered target:nil action:nil] autorelease];

        // Pass the selected object to the new view controller.
        [self.navigationController pushViewController:vehicleResultViewController animated:YES];

        [vehicleResultViewController setDelegate:self];

        if (indexPath.row == 0) 
        {
            vehicleResultViewController.title = @"Manufacture";
            [vehicleResultViewController setRequestString:@"ID.xml"]; //sets the request string in searchResultsViewController
            vehicleResultViewController.dataSetToParse = @"ID"; // This is used to controll what data is shown on subview... logic
            [vehicleResultViewController setAccessoryIndexPath:manufactureResultIndexPath]; //sends indexpath back to subview for accessory tick
            vehicleResultViewController.parentViewSelectedIndexPath = indexPath;
        }


//etc etc
}

И, наконец, я передаю его методу в моем подразделе, который передает indexpath в oldCheckedData.

- (void)setAccessoryIndexPath:(NSIndexPath *)myLastIndexPath
{
                oldCheckedData = myLastIndexPath;
                [self.tableView reloadData]; //<<---- this is where I reload the table to show the tick...
}

person C.Johns    schedule 14.10.2011    source источник


Ответы (2)


Попробуйте переместить строки cell.accessoryType = в функцию делегата willDisplayCell: следующим образом:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {

    // You can move this one here too:
    cell.selectionStyle = UITableViewCellSelectionStyleNone; // no blue selection

    if (indexPath == oldCheckedData) {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    } else {
        cell.accessoryType = UITableViewCellAccessoryNone;
    } 
}

Я читал, что метод willDisplayCell: следует использовать для любых основных визуальных изменений ячейки, таких как selectionStyle/accessoryType, и метод cellForRowAtIndexPath: для операций, связанных с данными ячейки, таких как установка текста, изображений и т. д.

person chown    schedule 14.10.2011
comment
Хорошо, спасибо, я попробую.. потому что я заметил, когда отлаживал, что ifstatment вызывается для каждой ячейки в текущем представлении.. так что это кажется довольно неэффективным... Я дам вам знать, как я иду. - person C.Johns; 14.10.2011
comment
@C.Johns Круто, и если он все еще не работает, можете ли вы опубликовать код, в котором вы устанавливаете oldCheckedData. Проверка if против oldCheckedData может быть нарушена из-за того, что что-то происходит с oldCheckedData во время загрузки таблицы. - person chown; 14.10.2011
comment
Хорошо, поэтому добавил, что он работает точно так же, как и раньше.. показывает некоторые тики вверх, но не вниз... Выложу код в том порядке, в котором он сейчас называется., спасибо за помощь, надеюсь, вы увидеть что-то, чего у меня нет. - person C.Johns; 14.10.2011
comment
@C.Johns Присоединяйтесь к чату: chat.stackoverflow.com/rooms/4252 /room-for-chown-and-c-johns - person chown; 14.10.2011
comment
Привет, Чаун, спасибо за помощь на днях. У меня все еще есть проблема после внесения множества различных исправлений.. но я решил двигаться дальше и вернуться к этому позже... какая головная боль. - person C.Johns; 17.10.2011

Недавно я столкнулся с этой проблемой, если оказалось, что в моем случае в ячейке установлен набор аксессуаров. Этот фрагмент гарантирует удаление представления.

 public func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {

..logic here to to determine if cell should be selected...

if ( cell.accessoryView != nil) {
    cell.accessoryView?.removeFromSuperview()
    cell.accessoryView = nil
}
cell.accessoryType = .checkmark
person David Berry    schedule 04.05.2019