Перезагрузка UITableView за UISearchDisplayController

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

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

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


person Ethan Vaughan    schedule 05.09.2010    source источник
comment
Та же проблема, больше скриншотов: stackoverflow .com/questions/14994997/   -  person Douglas    schedule 01.04.2013
comment
Удивительно, но 2 года спустя это все еще проблема: openradar.appspot.com/14676046 Похоже, Apple никогда не исправлено, потому что они заменили UISearchDisplayController в iOS 8.   -  person Keab42    schedule 23.10.2015


Ответы (8)


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

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

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

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

В моем случае я использую два 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.

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

person Derrek    schedule 08.05.2011

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

  1. В viewForHeaderInSection вернуть nil, если self.searchDisplayController.active ДА
  2. В didHideSearchResultsTableView вызовите [self.tableView reloadData], чтобы перезагрузить заголовки, когда таблица поиска исчезнет
person EricS    schedule 12.11.2013

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

person Jason G    schedule 19.11.2012

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

- (void)searchDisplayController:(UISearchDisplayController *)controller didHideSearchResultsTableView:(UITableView *)tableView
{
   [self.tableView reloadRowsAtIndexPaths:[self.tableView indexPathsForVisibleRows] withRowAnimation:UITableViewRowAnimationNone];
}
person DJ Tarazona    schedule 07.05.2014
comment
Это сработало для меня. У меня был раздел, перезагружаемый каждую секунду, из-за чего заголовок отображался поверх моей таблицы поиска. По какой-то причине работает перезагрузка того, что видно, а не указание самих indexPaths. Наверняка баг. - person Beau Nouvelle; 14.05.2014
comment
Это будет работать только в том случае, если базовая модель данных не изменилась. - person vincentjames501; 16.01.2015

Починил это..

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

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

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

person kirans_6891    schedule 03.12.2013

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

person han    schedule 31.03.2015

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

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

person Lytic    schedule 01.09.2015

Надеюсь, вы уже поняли это, но на случай, если кто-то наткнется на этот вопрос: это, вероятно, происходит потому, что ваш 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
}
person Cameron Spickert    schedule 07.04.2011
comment
Удивительно, но на самом деле проблема в том, что фактические заголовки разделов из UITableView в фоновом режиме отображаются над UITableView UISearchDisplayController. При прокрутке результатов поиска заголовки фоновых разделов отображаются фиксированными, плавающими над результатами поиска, когда результаты поиска перемещаются вверх и вниз за ними. - person Douglas; 01.04.2013
comment
Я вижу то же самое - плавающие заголовки из таблицы внизу. Мы смогли обойти проблему в iOS 6, вызвав [self.searchDisplayController.searchResultsTableView reloadData] в определенных местах, но это не работает в iOS 7. - person EricS; 12.11.2013