UISearchBar не будет отвечать в UISplitviewController Master

У меня довольно стандартная настройка UITableview как главного контроллера в UISplitviewController , универсальном приложении iOS9 .

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

 self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil]; self.searchController.searchResultsUpdater = self; self.searchController.dimsBackgroundDuringPresentation = NO; self.searchController.hidesNavigationBarDuringPresentation = NO; [self.searchController.searchBar sizeToFit]; self.tableView.tableHeaderView = self.searchController.searchBar; self.definesPresentationContext = YES; 

Не нужно показывать остальную часть моего кода, поиск и всю работу, как ожидалось, на iPhone . Моя проблема в том, что панель поиска никогда не получает фокус или не представляет клавиатуру при работе на iPad . Никакой ответ, кажется, не получает прикосновений. Даже не реагирует на программную попытку стать becomeFirstResponder .

Ничего не произошло.

Строка поиска видна и размещена соответствующим образом, нет проблем с подкладкой или наложением.

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

Дополнительное примечание. Если я использую многозадачность для сокращения раздвоенного вида, чтобы рухнуть на iPad, панель поиска работает так же, как и на iPhone . Это определенно связано с свернутым состоянием разделения.

ОБНОВЛЕНИЕ: (ближе)

После дальнейших экспериментов я обнаружил, что панель поиска работает на iPad, если вы запускаете приложение в ландшафте. В портретном режиме мой основной контроллер скрыт. Он displayModeButtonItem путем выбора displayModeButtonItem , который устанавливается в leftBarButtonItem подробно контроллера. То есть, когда searchBar ломается и больше не будет реагировать на касания.

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

Я попытался переместить definesPresentationContext в метод viewWillAppear главного контроллера, но это не повлияло.

Дальнейшее обновление:

Еще одно неожиданное обстоятельство заключается в том, что проблем с панелью поиска вообще нет на iPhone 6plus. Работает независимо от ориентации, рушится или нет и не имеет значения, в каком состоянии она начинается. Я ожидаю, что это будет так же, как iPad, когда в альбомной ориентации. Полностью работает на iPhone .

Я до сих пор не понял этого. Моя последняя попытка исправить, я переместил всю инициализацию контроллера поиска в метод viewDidLayoutSubviews . Никаких изменений.

Кроме того, я заметил, что когда поиск активен, экранная клавиатура, если я поворачиваю iPad, клавиатура уходит, но панель поиска остается активной. Сначала я не понял, потом увидел, что кнопка отмены все еще отображается. Он не получит прикосновений и не имеет клавиатуры, но, по-видимому, это еще первый ответчик.

Пример проекта, загруженного в GitHub: репозиторий Github

ПРИМЕЧАНИЕ. Не было проблем, пока я не добавил в проект мои методы UISplitview Delegate. Я хотел бы сразу добавить это к моему вопросу, поэтому я даже не пытался понять, как эти методы делегирования влияют на панель поиска, но, очевидно, проблема там создается где-то.

Обновить:

Я попробовал еще несколько вариантов без успеха.

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

Я также посмотрел на иерархию представлений в профилировщике, панель поиска – это верхний уровень, не охватываемый ничем другим.

Финальная обертка:

Обходное решение @tomSwift действительно исправило мою проблему на iPad. При дальнейшем тестировании я обнаружил, что он нарушил мой интерфейс iPhone. Предположительно, это больше проблема с моей собственной настройкой и временем создания контроллеров Master / Detail View. Казалось бы, некоторые важные объекты больше не были созданы вовремя, поскольку, возможно, контроллер подробного представления еще не существовал. Я попытался исправить, переместив критические элементы в App Delegate, но это стало громоздким, и я не мог его легко сузить, поэтому я взломал исправление:

 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible; } 

Более элегантное решение, скорее всего, будет, но это заняло достаточно моего времени. Сейчас все работает. Радиолокационная станция – 28304096

Это явно ошибка в UISplitViewController и / или UISearchController . Конечно, подайте радар с Apple и прикрепите свой образец кода.

Я думаю, что ошибка включает UISplitViewController.displayMode UISplitViewControllerDisplayModeAutomatic . Когда я меняю preferredDisplayMode на UISplitViewControllerDisplayModeAllVisible тогда все начинает работать:

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. UISplitViewController *splitViewController = (UISplitViewController *)self.window.rootViewController; UINavigationController *navigationController = [splitViewController.viewControllers lastObject]; navigationController.topViewController.navigationItem.leftBarButtonItem = splitViewController.displayModeButtonItem; splitViewController.delegate = self; splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible; return YES; } 

Главное, что это изменение – это макет по умолчанию для портрета на iPad, который, как я понимаю, может быть не идеальным. Я также играл с настройкой preferredDisplayMode на UISplitViewControllerDisplayModeAllVisible изначально, затем устанавливая его обратно в UISplitViewControllerDisplayModeAutomatic ; это отлично работало до тех пор, пока экранная ориентация не изменилась – тогда все это снова сломалось. Возможно, вам удастся пойти дальше по этому пути.

Я также AppDelegate следующее дополнение в AppDelegate , чтобы заставить контроллер поиска деактивировать displayMode . (Я также должен был searchController свойство searchController публично в MasterViewController).

 - (void)splitViewController:(UISplitViewController *)svc willChangeToDisplayMode:(UISplitViewControllerDisplayMode)displayMode { UINavigationController *navigationController = [svc.viewControllers firstObject]; MasterViewController* mvc = (MasterViewController*) navigationController.topViewController; [mvc.searchController setActive: NO]; } 

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

Используйте этот метод делегата для создания уведомления:

 - (void)splitViewController:(UISplitViewController *)svc willChangeToDisplayMode:(UISplitViewControllerDisplayMode)displayMode { NSLog(@"WILL CHANGE TO DISPLAY MODE: %ld", (long)displayMode); NSNumber *displayNumber = [NSNumber numberWithInteger:displayMode]; NSDictionary *userInfo = @{ @"displayMode": displayNumber }; NSNotification *modeChangedNotif = [NSNotification notificationWithName:@"modeChanged" object:nil userInfo:userInfo]; [[NSNotificationCenter defaultCenter] postNotification:modeChangedNotif]; } 

Затем в вашем MasterViewController вы можете сделать это в viewDidLoad :

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(modeChanged) name:@"modeChanged" object:nil]; 

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

 - (void) modeChanged { [self.searchController setActive:YES]; } 
Interesting Posts
Давайте будем гением компьютера.