Перезагрузка UITableView за UISearchDisplayController - PullRequest
15 голосов
/ 05 сентября 2010

Я столкнулся с этим действительно странным явлением, которое не могу понять.У меня есть UITableViewController, который управляет UITableView.Довольно простоУ меня также есть UISearchDisplayController для поиска содержимого табличного представления.Функция поиска сможет удалять элементы содержимого, отображаемого в табличном представлении.Поэтому, если пользователь решит удалить один из элементов, найденных им во время поиска, я хочу не только перезагрузить табличное представление UISearchDisplayController, но и табличное представление UITableViewController.Когда я это делаю, разделы обычного табличного представления появляются и отображаются над UISearchDisplayController.Это действительно довольно странно.Я думаю, что лучший способ объяснить это с помощью изображения:

http://img46.imageshack.us/img46/2818/screenshot20100905at140.png

Если кто-то из вас знает, что может быть причиной этой проблемы, или знает обходной путь, это было бы замечательно.

Ответы [ 9 ]

7 голосов
/ 08 мая 2011

ОБНОВЛЕНО СНОВА

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

Я решил эту проблему, отключив fetchedResultsController (установив его в ноль) и позволив ему снова загружаться лениво при необходимости, когда поиск исчезает.

ОБНОВЛЕНО - Оригинальный ответ ниже

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

Я обнаружил, что предотвращение анимации при добавлении заголовков разделов предотвращает эту ошибку. Так что пока searchDisplayController.active я просто отключаю анимацию смены раздела. см. код ниже.

- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
           atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
    if (!self.reordering) {
        UITableView *myTableView = controller == __fetchedResultsController ? self.tableView : self.searchDisplayController.searchResultsTableView;
        UITableViewRowAnimation animation;
        if (self.searchDisplayController.active) {
            animation = UITableViewRowAnimationNone;
        } else {
            animation = UITableViewRowAnimationFade;
        }

        switch(type)
        {
            case NSFetchedResultsChangeInsert:
                [myTableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:animation];
                break;

            case NSFetchedResultsChangeDelete:
                [myTableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:animation];
                break;
        }
    }
}

ОРИГИНАЛЬНЫЙ ОТВЕТ

Другой ответ на самом деле не работает сам по себе. Причина в том, что отображаемый заголовок не является заголовком в табличном представлении searchDisplayController. Это заголовок основного табличного представления, который по какой-то причине добавляется над табличным поиском в иерархии представлений.

Я решил эту проблему, отключив обновления для основной таблицы, пока searchDisplayController.active = YES.

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

- (void)searchDisplayController:(UISearchDisplayController *)controller didHideSearchResultsTableView:(UITableView *)tableView {
    [self.tableView reloadData];
}

- (void)searchDisplayController:(UISearchDisplayController *)controller willShowSearchResultsTableView:(UITableView *)tableView {
    self.fetchedResultsController.delegate = nil;
    self.fetchedResultsController = nil;
}

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

У кого-нибудь есть лучшее решение для этого? Кажется, что это допустимая ошибка для viewForHeaderInSection и titleForHeaderInSection, когда данные перезагружаются, когда они покрыты UISearchDisplayController.

Самый простой ответ для меня - попытаться переопределить представление поиска, чтобы вы не могли видеть фоновую таблицу. Но это лишает Appleness приложения.

3 голосов
/ 12 ноября 2013

Наше решение заключается в следующем.Он был протестирован только в iOS 7:

  1. В viewForHeaderInSection, верните nil, если self.searchDisplayController.active - ДА
  2. В didHideSearchResultsTableView, вызовите [self.tableView reloadData], чтобы перезагрузить заголовкикогда исчезает таблица поиска
2 голосов
/ 07 мая 2014

Я решил это в iOS 7, перезагрузив только видимые строки в базовой таблице.

- (void)searchDisplayController:(UISearchDisplayController *)controller didHideSearchResultsTableView:(UITableView *)tableView
{
   [self.tableView reloadRowsAtIndexPaths:[self.tableView indexPathsForVisibleRows] withRowAnimation:UITableViewRowAnimationNone];
}
2 голосов
/ 19 ноября 2012

Я тоже столкнулся с этим недавно ... подход, который я решил, заключался в том, чтобы ставить обновления в основной tableView в очереди приостановленной последовательной отправки, пока UISearchDisplayController не скрывает searchResultsTableView. Вероятно, я бы посчитал это ошибкой, поскольку заголовки разделов не должны отображаться в основном tableView, если searchResultsTableView занял этот слой.

0 голосов
/ 01 сентября 2015

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

Мне пришлось установить символическую точку останова на UITableView reloadData, чтобы найти все вызовы для перезагрузкикоторые заставляли заголовки раздела перерисовываться в верхней части таблицы поиска.

0 голосов
/ 31 марта 2015

Из-за использования UITableViewController.self.view - это TableView в UITableViewController, а SearchDisplayController ContainerView добавляется к self.view из UITableViewController.Просто используйте UIViewcontroller.

0 голосов
/ 14 января 2015
[self.searchDisplayController.searchResultsTableView reloadData];
0 голосов
/ 03 декабря 2013

Исправлено ..

Добавьте следующие строки в viewDidLoad

searchDisplayController.searchResultsTableView.delegate = self;
searchDisplayController.searchResultsTableView.dataSource = self;

Это исправило это для меня ...

0 голосов
/ 07 апреля 2011

Надеюсь, вы уже поняли это, но на тот случай, если кто-то столкнется с этим вопросом: это, вероятно, происходит потому, что ваш UITableViewController является источником данных / делегатом для таблицы поиска, а также для вашей основной таблицы. То есть, по-видимому, у вас одинаковые методы UITableViewDelegate / DataSource, выполняющиеся для обоих табличных представлений, и вы возвращаете одинаковый заголовок раздела для обеих таблиц. Убедитесь, что вы обрабатываете таблицу результатов поиска отдельно:

- (NSString *)tableView:(UITableView *)aTableView titleForHeaderInSection:(NSInteger)section {
    if (aTableView == [[self searchDisplayController] searchResultsTableView]) {
        return nil;
    }
    // Return a title appropriate for self.tableView here
}
...