Подтвердить что ты не робот

UISearchController не перерисовывает навигационную панель при повороте

Я реализовал UISearchController, и он отлично работает, кроме...

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

enter image description here

Однако, когда я поворачиваю телефон обратно в портретный вид (все еще выбранный в области типа поиска), я получаю следующее представление.

enter image description here

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

self.venueSearchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.venueSearchController.searchResultsUpdater = self;
self.venueSearchController.searchBar.delegate = self;
self.venueSearchController.dimsBackgroundDuringPresentation = NO;
self.venueSearchController.hidesNavigationBarDuringPresentation = YES;
self.venueSearchController.searchBar.frame = CGRectMake(self.venueSearchController.searchBar.frame.origin.x, self.venueSearchController.searchBar.frame.origin.y, self.venueSearchController.searchBar.frame.size.width, 44.0);

self.definesPresentationContext = YES;

self.navigationController.navigationBar.translucent = YES;
self.venueSearchController.searchBar.translucent = YES;

self.tableView.tableHeaderView = self.venueSearchController.searchBar;
4b9b3361

Ответ 1

Похоже, что UISearchController забывает reset кадр searchBar при появлении строки состояния. Я думаю, что это, вероятно, ошибка в UISearchController; кажется, что некоторые из них перечислены в radar. Кажется, что searchBar superview (который является внутренним для UISearchController) заканчивается с неправильной высотой. Это вызывает недовольство, поскольку поэтому решение включает вхождение в иерархию представлений searchController, которые Apple может изменить... вы можете добавить проверку версии iOS, чтобы она выполнялась только для определенных версий.

Если вы добавите код ниже в свой контроллер просмотра, он будет вызываться, когда изменяется коллекция признаков. Он проверяет, что: a) активный контроллер поиска, b) статусBar не скрыт, и c) источник searchBar-y равен 0, и если это так, он увеличивает высоту надзора на высоту statusBar, которая перемещается searchBar.

override func traitCollectionDidChange(previousTraitCollection: UITraitCollection?) {
    let app = UIApplication.sharedApplication()
    if searchController!.active && !app.statusBarHidden && searchController?.searchBar.frame.origin.y == 0 {
        if let container = self.searchController?.searchBar.superview {
            container.frame = CGRectMake(container.frame.origin.x, container.frame.origin.y, container.frame.size.width, container.frame.size.height + app.statusBarFrame.height)
        }
    }
}

Цель C

- (void) traitCollectionDidChange: (UITraitCollection *) previousTraitCollection {

    [super traitCollectionDidChange: previousTraitCollection];

    if(self.venueSearchController.active && ![UIApplication sharedApplication].statusBarHidden && self.venueSearchController.searchBar.frame.origin.y == 0)
    {
        UIView *container = self.venueSearchController.searchBar.superview;

        container.frame = CGRectMake(container.frame.origin.x, container.frame.origin.y, container.frame.size.width, container.frame.size.height + [UIApplication sharedApplication].statusBarFrame.size.height);
    }
}

Ответ 2

Вам может потребоваться реализовать UIBarPositioningDelegate в вашем контроллере вида.

self.venueSearchController.searchBar.delegate = self;

SearchBar ищет ответ от этого делегата.

@protocol UISearchBarDelegate <UIBarPositioningDelegate> 

Добавьте следующее в свой self (я предполагаю, что это ViewController)

#pragma mark - <UIBarPositioningDelegate>

// Make sure NavigationBar is properly top-aligned to Status bar
- (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar
{
    if (bar == self.venueSearchController.searchBar) {
        return UIBarPositionTopAttached;
    }
    else { // Handle other cases
        return UIBarPositionAny;
    }
}

Ответ 3

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

Я думаю, вы можете решить эту проблему, заменив ваш UITableViewController на UIViewController, в который вы удаляете UITableView. Затем установите верхнее ограничение представления таблицы в качестве верхнего руководства по макету. Установите боковые ограничения влево, вправо, внизу 0.

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

Смотрите это обсуждение: iOS 7: UITableView отображается в строке состояния

Ответ 4

Я столкнулся с аналогичной проблемой с UISearchController, используя его с navigationItem. Это выглядит по-другому, но вызвано той же самой проблемой: UISearchController НЕ обновляет кадр searchBar, когда появляется строка состояния.

Но вместо ручной настройки кадров иерархии представления searchBar вы должны просто заставить его обновить макет, переключая hidesNavigationBarDuringPresentation назад и вперед во время поворота в traitCollectionDidChange или viewWillTransition(to size: CGSize, with cooridnator: UIViewControllerTransitionCoordinator):

Таким образом, исправление будет выглядеть так:

 override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
    super.traitCollectionDidChange(previousTraitCollection)
    if #available(iOS 11, *) {
        navigationItem.hidesSearchBarWhenScrolling.toggle()
        navigationItem.hidesSearchBarWhenScrolling.toggle()
    }
}

А вот как выглядит оригинальный выпуск.

Search in landscape without status bar

Затем вращается и получил это:

Search in portrait after status bar reappearing

Ответ 5

Я временно "исправил" это, отключив "Скрыть строку состояния" в настройках.

enter image description here