Анимация UIViewController, вызываемая pushViewController, отображается дважды

У меня есть UISearchBar, и я хочу отобразить другой UIViewController, когда я нажимаю кнопку поиска в UISearchBar. Я использую для этого следующий метод:

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
    UIStoryboard* storyboard = [UIStoryboard storyboardWithName:@"Main"
                                                         bundle:nil];
    UIViewController *add =
    [storyboard instantiateViewControllerWithIdentifier:@"mainMenuViewController"];

    [self.navigationController pushViewController:add animated:YES];
}

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

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

Метод делегата searchBarSearchButtonClicked вызывается только один раз.

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

А вот UIVIewCONtroller с панелью поиска выглядит так:

- (void)viewDidLoad {
    [super viewDidLoad];

    UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 100, 20)];
    searchBar.placeholder = NSLocalizedString(@"search a pub or a place", nil);
    searchBar.delegate = self;
    [self.navigationItem setTitleView:searchBar];

}

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
    DLog(@"Filter searchBarSearchButtonClicked");
    UIStoryboard* storyboard = [UIStoryboard storyboardWithName:@"Main"
                                                         bundle:nil];
    UIViewController *add =
    [storyboard instantiateViewControllerWithIdentifier:@"mainMenuViewController"];

    [self.navigationController pushViewController:add animated:YES];
}

Проблема как на iOS 8, так и на 9.

Изменить:

Я загрузил образец проекта здесь. Это очень минималистично.

Изменить2:

Если я представляю контроллер так, а не через контроллер навигации, анимация отображается только один раз. (Хотя это другая анимация - снизу вверх, предыдущая была справа налево). Но мне нужно сделать это через навигационный контроллер. Таким образом, проблема, похоже, связана с UISearchBar Search + Navigation Controller.

[self presentViewController:add
                   animated:YES
                 completion:nil];

Конечно, я также могу вызвать это без анимации, например:

[self.navigationController pushViewController:add animated:NO];

Но что, если я хочу анимацию.

Изменить3:

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

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
    [self performSegueWithIdentifier:@"seg1" sender:self];
}

Изменить4:

Я сообщил об этой ошибке в Apple, потому что я предполагаю, что это ошибка в UIKit. В любом случае, если кто-то найдет обходной путь, будет хорошо.


comment
Может быть, что-то путается с увольнением UISearchController. Можно попробовать переместить код делегата кнопки в метод с простой сигнатурой, а затем вызвать его с помощью self performSelector.   -  person danh    schedule 01.07.2016
comment
спасибо за идею, я попробовал, но проблема осталась.   -  person luky    schedule 04.07.2016


Ответы (1)


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

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

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar 
{
    [self.navigationItem.titleView removeFromSuperview];

    // and so on with the OP code...

Как ни странно, это устраняет проблему с дополнительной анимацией, но на самом деле не удаляет панель поиска. Проверка titleView сразу после удаления показывает, что панель поиска все еще существует.

person danh    schedule 05.07.2016
comment
Отличный улов! Так что я не знаю, стоит ли мне полагаться на это хакерское решение, так как оно тоже выглядит глючным (если не удаляет представление) - но да, оно работает. Какую кнопку я мог бы добавить в качестве подвида и где? - person luky; 18.07.2016
comment
может быть, я мог бы положиться на это хакерское решение, например, если оно работает в момент компиляции, оно будет работать вечно, независимо от того, исправит ли Apple удаление в какой-то будущей версии или нет. Я не уверена. Зависит от того, связан ли UIKit со скомпилированным приложением или вызывается динамически. - person luky; 18.07.2016
comment
Рад, что это было полезно. Я бы справился с этим, используя UISearchController, как рекомендовано в документации. Предлагаемый здесь хак состоит в том, чтобы обойти оригинальный хак панели поиска в виде заголовка. - person danh; 18.07.2016
comment
Спасибо. У меня хорошие новости! Я обнаружил, что ошибка анимации также возникает, если вы фокусируете UINavigationBar, а затем нажимаете какой-либо обычный UIButton, чтобы показать новый контроллер. (Что отлично работало, если UINavigationbar не был сфокусирован!) Значит, проблема тоже связана с фокусом! Это означает, что проблема решена также, если вы вызываете это: [self.navigationItem.titleView resignFirstResponder]; перед отображением нового контроллера. Но твоя идея тоже пригодилась. - person luky; 20.07.2016