Arhn - архитектура программирования

Ошибка утверждения при попытке перезагрузить разделы

Я создаю одно табличное приложение, используя библиотеку TQMultistageTableView для расширения разделов. Мое требование: если пользователь будет нажимать на разделы таблицы, тогда цвет фона раздела должен измениться на синий цвет, цвет фона остального раздела должен быть белым, если он не выбран/расширен. Для этого я создал массив для сохранения индекса раздела, а затем перезагружаю этот раздел.

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

*** Ошибка утверждения в -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-2935.137/UITableView.m:1368

*** Завершение работы приложения из-за необработанного исключения «NSInternalInconsistencyException», причина: «Недопустимое обновление: недопустимое количество строк в разделе 1. Количество строк, содержащихся в существующем разделе после обновления (0), должно быть равно количеству строк. содержащихся в этом разделе до обновления (3), плюс или минус количество строк, вставленных или удаленных из этого раздела (0 вставленных, 0 удаленных) и плюс или минус количество строк, перемещенных в этот раздел или из него (0 перемещенных в , 0 съехал)'.

Вот мой код:

//метод открытия заголовка

- (void)mTableView:(TQMultistageTableView *)mTableView1 willOpenHeaderAtSection:(NSInteger)section
{
    NSLog(@"Open Header ----%ld",section);
    NSDictionary *selectedSection = [NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"%ld", (long)section] ,@"section" ,nil];

    for(int i=0;i<[ selectedArrayForSectionPlus count];i++)
    {
        if([[[selectedArrayForSectionPlus objectAtIndex:i] objectForKey:@"section"] isEqualToString:[NSString stringWithFormat:@"%ld", (long)section]])
        {
            [selectedArrayForSectionPlus removeObjectAtIndex:i];
            [self.mTableView.tableView reloadSections:[NSIndexSet indexSetWithIndex:section] withRowAnimation:UITableViewRowAnimationFade];

            return;
        }
    }

    [selectedArrayForSectionPlus addObject:selectedSection];

    [self.mTableView.tableView reloadSections:[NSIndexSet indexSetWithIndex:section] withRowAnimation:UITableViewRowAnimationFade];//here it is crashing
}

//метод закрытия заголовка

- (void)mTableView:(TQMultistageTableView *)mTableView willCloseHeaderAtSection:(NSInteger)section
{    
    NSLog(@"Close Header ---%ld",section);

    for(int i=0;i<[ selectedArrayForSectionPlus count];i++)
    {
        if([[[selectedArrayForSectionPlus objectAtIndex:i] objectForKey:@"section"] isEqualToString:[NSString stringWithFormat:@"%ld", (long)section]])
        {
            [selectedArrayForSectionPlus removeObjectAtIndex:i];
            [self.mTableView.tableView reloadSections:[NSIndexSet indexSetWithIndex:section] withRowAnimation:UITableViewRowAnimationFade];

            return;
        }
    }
}

//метод viewForHeaderInSection

- (UIView *)mTableView:(TQMultistageTableView *)mTableView viewForHeaderInSection:(NSInteger)section;
{
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.mTableView.frame.size.width, 80)];

    for (int i = 0; i<selectedArrayForSectionPlus.count; i++) {
        if([[[selectedArrayForSectionPlus objectAtIndex:i] objectForKey:@"section"] isEqualToString:[NSString stringWithFormat:@"%ld", (long)section]])
        {

            [view setBackgroundColor:[UIColor colorWithRed:0/255.0 green:150/255.0 blue:214/255.0 alpha:1.0]];

        }
        else
        {
            [view setBackgroundColor:[UIColor whiteColor]];
        }
    }

    return view;
}

Кто-нибудь знает, как перезагрузить раздел?

Спасибо за любые указатели!


Ответы:


1

Инкапсулируйте вызовы перезагрузки раздела в beginUpdates и endUpdates примерно так:

[self.mTableView.tableView beginUpdates];
[selectedArrayForSectionPlus removeObjectAtIndex:i];
[self.mTableView.tableView reloadSections:[NSIndexSet indexSetWithIndex:section] withRowAnimation:UITableViewRowAnimationFade];
[self.mTableView.tableView endUpdates];

EDIT: опубликовать обсуждение с OP.

  1. Нажмите на раздел 1, чтобы вызвать willOpenHeaderAtSection. Следите за прослушиваемой секцией здесь.
  2. Нажмите на раздел 2, чтобы вызвать willCloseHeaderAtSection. Сопоставьте раздел с отслеживаемым разделом в № 1. Если совпадения, выполните свой код willCloseHeaderAtSection и сбросьте отслеживаемый раздел. Если не совпадает, просто вернитесь без выполнения кода.
19.11.2015
  • @AbhinavСпасибо за ваш ответ, я попытался перезагрузить раздел, используя beginUpdates и endUpdates, но все равно вылетает. 19.11.2015
  • Не могли бы вы дважды проверить объект вашей модели, который содержит данные для строк и разделов. Перед каждым вызовом перезагрузки вам необходимо убедиться, что ваша модель содержит правильные данные. 19.11.2015
  • Проблема заключается в том, что если я нажимаю на второй раздел, то вызывается только 'willOpenHeaderAtSection', и после этого, если я снова нажимаю на первый раздел, то 1. 'willCloseHeaderAtSection' и 2. 'willOpenHeaderAtSection' вызывает. 19.11.2015
  • Мой код работает нормально, если я нажимаю на любой раздел, когда другие разделы закрыты. 19.11.2015
  • Попался. Вам нужно будет справиться с этим немного хитрым способом. Поскольку вы удаляете объекты, когда вызывается willCloseHeaderAtSection, это создает проблему, когда iOS запускает вызов этого метода, когда вы нажимаете на любой другой раздел, чтобы развернуть его. Вы должны отслеживать текущий открытый/расширенный раздел ячейки в willOpenHeaderAtSection и выполнять свой код внутри willCloseHeaderAtSection только тогда, когда раздел совпадает, в противном случае просто вернитесь. Сбросьте отслеживаемый раздел, если он совпадает, и выполните свой код в willCloseHeaderAtSection. Надеюсь, вы понимаете, что я имею в виду. 19.11.2015
  • Я понял вашу точку зрения, но willCloseHeaderAtSection вызывается перед методом willOpenHeaderAtSection, тогда как я могу выполнить код только внутри willCloseHeaderAtSection. 19.11.2015
  • Взгляните на мой обновленный пост. Это алгоритм высокого уровня, как я и хотел. 19.11.2015
  • Давайте продолжим обсуждение в чате. 19.11.2015
  • Спасибо, этот ответ помог мне. 08.06.2017

  • 2

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

    Я думаю, вы обновляете источник данных перед вызовом раздела перезагрузки.

    Вот ваша проблема

    Вы перезагружаете не раздел 1 а какой-то другой. Перед перезагрузкой ваш источник данных (массив данных) содержит три строки (записи) для раздела 1, но когда вы перезагружаете раздел, по какой-то причине ваш источник данных (индекс массива данных 1) изменяется на 0 строк (записей). индекс 1 источника данных (массив данных) должен содержать три строки.

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

    19.11.2015
  • @M Зубаир Шамшад Я проверил источник данных, мой массив строк совершенно другой. Он работает нормально, если я нажимаю на любой раздел, когда другие разделы закрыты. Только проблема в том, что один раздел уже расширен, и я нажимаю на другой раздел. 19.11.2015
  • я уверен, что ваш массив данных по какой-то причине изменился. отчет о сбое говорит то же самое, что я говорю. 19.11.2015
  • Это также может быть возможно, так как происходит сбой в методе openOrCloseHeaderWithSection библиотеки TQMultistageTableView, я не могу решить эту проблему. 19.11.2015
  • Хорошо, давайте проверим... поставьте точку останова или nslog в методе numnerOfRowsInSection. и сравните количество строк для раздела 1 до и после вызова раздела перезагрузки, используя один и тот же сценарий сбоя. 19.11.2015
  • Я тестировал в том же сценарии, до того, как количество строк для раздела 1 равно 4, и после reloadSections метода willOpenHeaderAtSection... его сбой напрямую без вызова метода numberOfRowInSection. 19.11.2015
  • каково значение section в willOpenHeaderAtSection, если оно выходит за пределы таблицы??? 19.11.2015
  • Вместо reloadSections, если я перезагружаю свою таблицу reloadData, то количество строк до и после будет правильным. Но после этого происходит сбой в методе openOrCloseHeaderWithSection библиотеки TQMultistageTableView. 19.11.2015
  • Давайте продолжим обсуждение в чате. 19.11.2015

  • 3

    Вот ваша проблема:

    [self.mTableView.tableView reloadSections:[NSIndexSet indexSetWithIndex:section] withRowAnimation:UITableViewRowAnimationFade];
    

    Поэтому перед использованием этой строки добавьте [_mTableView reloadtable];

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

    если ваша проблема решена в строке выше, то все в порядке....

    21.11.2015
  • перезагрузка всей таблицы никогда не должна выполняться непосредственно перед перезагрузкой раздела этой таблицы. 16.08.2017

  • 4

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

    [self.mTableView.tableView reloadSections:[NSIndexSet indexSetWithIndex:section] withRowAnimation:UITableViewRowAnimationFade];
    

    и еще одна вещь, которую вам нужно сделать, это в файле TQMultistageTableView.m имя метода -(void)openOrCloseHeaderWithSection:(NSInteger)section просто вставить ниже код и все готово

      [self.tableView beginUpdates];
    NSMutableArray *deleteIndexPaths = [[NSMutableArray alloc] init];
    NSMutableArray *insertIndexPaths = [[NSMutableArray alloc] init];
    
    NSInteger oldSection = self.openedIndexPath.section;
    NSInteger newSection = section;
    
    if (oldSection <= -1)
    {
    
        if (oldSection != newSection)
        {
            insertIndexPaths = [self buildInsertRowWithSection:newSection];
        }
    }
    else
    {
    
        if (oldSection != newSection && newSection > -1)
        {
    
            deleteIndexPaths = [self buildDeleteRowWithSection:oldSection];
            insertIndexPaths = [self buildInsertRowWithSection:newSection];
        }
        else
        {
             deleteIndexPaths = [self buildDeleteRowWithSection:oldSection];
        }
    }
    
    
    if ([deleteIndexPaths count] > 0)
    {
        [self.tableView deleteRowsAtIndexPaths:deleteIndexPaths withRowAnimation:UITableViewRowAnimationFade];
    }
    if ([insertIndexPaths count] > 0)
    {
        [self.tableView insertRowsAtIndexPaths:insertIndexPaths withRowAnimation:UITableViewRowAnimationLeft];
    }
    
    [self.tableView endUpdates];
    
    16.03.2016
    Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..