Сохранение UINavigationController navigationBar скрыто после выбора UISearchDisplayController

У меня есть установка UISearchDisplayController с UITableViewController, которая вложена внутри UINavigationController. Когда выполняется выбор ячейки, запускается метод UITableView's didSelectRowAtIndexPath, который выталкивает новое представление родительскому контроллеру навигации. Этот новый вид должен иметь панель навигации, скрытую при входе.

[[self navigationController] setNavigationBarHidden:YES animated:NO];

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

Если я переведу вызов setNavigationBarHidden в метод целевого представления viewWillAppear, результаты будут похожи. Я могу заставить его работать, поместив вызов hide в viewDidAppear, но это создает очень неудобный переходный эффект, который кажется неустойчивым и неуместным. Я бы хотел, чтобы navigationBar уже был скрыт до того, как новое представление переместится на экран.

Кто-нибудь знает, где происходит невидимость навигации, и/или каким-либо образом я могу переопределить это поведение?

Ответы

Ответ 1

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

Вызывается метод:

-(void) hideNavBar {
    if (self.navigationController.navigationBar.hidden == NO)
    {
        [self.navigationController setNavigationBarHidden:YES animated:YES];
    }
}

Затем в методе viewDidLoad у меня есть следующее:

[self performSelector:@selector(hideNavBar) withObject:nil afterDelay:0.0];

Это работает и удаляет навигационную панель одним мгновенным махом. Вы можете изменить время задержки, если хотите, чтобы анимация была удалена после задержки. Я попробовал [self hideNavBar], но это просто не сработало, поэтому придерживаюсь того, что у меня выше.

Надеюсь, что это поможет, и если у кого-то есть более элегантное решение, мне интересно!

Ответ 2

Хорошо, это прослушивало меня пару часов, но я, наконец, получил его на работу! Кажется, проблема заключается в том, что UISearchDisplayController отслеживает, скрывает ли она панель навигации, и если она есть, она восстанавливает ее после отклонения представления. Вот почему со многими ответами выше вы видите хвост анимации бара, скрывающегося при новом нажатии. Однако, обманув контроллер дисплея поиска, мы можем изменить это поведение.

Сначала: Подкласс UISearchDisplayController

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

- (void)setActive:(BOOL)visible animated:(BOOL)animated
{
    if(self.active == visible)
        return;

    [self.searchContentsController.navigationController setNavigationBarHidden:YES animated:YES];
    [super setActive:visible animated:animated];

    if (visible)
        [self.searchBar becomeFirstResponder];
    else{
        [self.searchBar resignFirstResponder];
        [self.searchContentsController.navigationController setNavigationBarHidden:NO animated:YES];
    }
}

Обратите внимание, что мы скрываем навигационную панель, прежде чем будем называть функцию super setActive. Похоже, что суперкласс не пытается скрыть навигационную панель и, следовательно, от попытки восстановить ее выбор элемента. Теперь, когда контроллер становится активным, панель будет скрыта, как обычно. Также обратите внимание, что мы восстанавливаем навигационную панель, когда searchBar уходит в отставку с первого ответчика. Это приведет к восстановлению панели, если мы отменим контроллер.

Во-вторых: Скрыть панель навигации при выходе

Если мы скроем панель навигации в представлении, она исчезнет, ​​она будет скрыта:

-(void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];

    [self.navigationController setNavigationBarHidden:YES animated:animated];
}

Третий: скрыть панель навигации при возврате

Единственная проблема теперь в том, что, если мы выберем строку из отфильтрованного tableview, при возврате, панель навигации будет видна. Чтобы исправить это, нам нужно поставить чек в представлении. Появится:

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    if(self.isFiltered){
        [self.navigationController setNavigationBarHidden:YES animated:NO];
    }

}

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

Ответ 3

Натолкнувшись на ту же проблему, удалось заставить ее работать плавно с этим уродливым взломом:

- (void) viewWillDisappear: (BOOL) animated 
{
    if (searchController_.active)       
    {
        self.navigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent;
        self.navigationController.navigationBar.tintColor = nil;        
    }

    [super viewWillDisappear: animated];
}


- (void) viewWillAppear: (BOOL) animated 
{       
    if (searchController_.active)       
    {
        self.navigationController.navigationBar.barStyle = UIBarStyleDefault;
    }

    [super viewWillAppear: animated];
}

Ответ 4

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

-(void) viewWillLayoutSubviews{
  if (self.navigationController.navigationBar.hidden == NO)
  {
    [self.navigationController setNavigationBarHidden:YES animated:YES];
  }
}

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

Ответ 5

- (void) viewWillDisappear: (BOOL) animated
{
    // self.searchOn property tell if full screen search is enabled
    //if (self.searchOn)
    //{

        [self.navigationController setNavigationBarHidden:NO animated:NO];
    //}

    [super viewWillDisappear: animated];
}


- (void) viewWillAppear: (BOOL) animated
{
    //if (self.searchOn)
    //{
         [self.navigationController setNavigationBarHidden:YES animated:YES];
    //}

    [super viewWillAppear: animated];
}