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

У меня есть код ниже, который скрывает и показывает навигационную панель. Он скрыт, когда первый вид загружается, а затем скрывается, когда вызываются "дети". Проблема в том, что я не могу найти событие/действие, чтобы вызвать его, чтобы скрыть его снова, когда они вернутся к корневому представлению....

У меня есть кнопка "тест" на корневой странице, которая вручную выполняет действие, но не очень красива, и я хочу, чтобы она была автоматической.

-(void)hideBar 
{
    self.navController.navigationBarHidden = YES;
}
-(void)showBar 
{       
    self.navController.navigationBarHidden = NO;
}

Ответ 1

Самое приятное решение, которое я нашел, - это сделать следующее в контроллере первого представления.

Objective-C

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

- (void)viewWillDisappear:(BOOL)animated {
    [self.navigationController setNavigationBarHidden:NO animated:animated];
    [super viewWillDisappear:animated];
}

Swift

override func viewWillAppear(animated: Bool) {
    self.navigationController?.setNavigationBarHidden(true, animated: animated)
    super.viewWillAppear(animated)
}

override func viewWillDisappear(animated: Bool) {
    self.navigationController?.setNavigationBarHidden(false, animated: animated)
    super.viewWillDisappear(animated)
} 

Это приведет к тому, что навигационная панель будет лежать слева (вместе со следующим видом), когда вы нажимаете следующий UIViewController в стеке и анимируете влево (вместе со старым представлением), когда вы нажмите кнопку "Назад" на UINavigationBar.

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

Ответ 2

Другой подход, который я нашел, - установить делегат для NavigationController и установить значение NavigationBarHidden в navigationController:willShowViewController:animated:

- (void)navigationController:(UINavigationController *)navController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated{ 
// hide the nav bar if going home
if (viewController == homeViewController) [navController setNavigationBarHidden:YES animated:animated];
else [navController setNavigationBarHidden:NO animated:animated];}

Простой способ настроить поведение для каждого ViewController всего в одном месте.

Ответ 3

Я бы поместил код в делегат viewWillAppear на каждое отображаемое представление:

Так вот, где вам нужно скрыть это:

- (void)viewWillAppear:(BOOL)animated
{
        [yourObject hideBar];
}

Нравится это, когда вам нужно его показать:

- (void)viewWillAppear:(BOOL)animated
{
        [yourObject showBar];
}

Ответ 4

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

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

- (void) viewWillDisappear:(BOOL)animated
{
    if (self.navigationController.topViewController != self)
    {
        [self.navigationController setNavigationBarHidden:NO animated:animated];
    }

    [super viewWillDisappear:animated];
}

Ответ 5

в Swift 3:

override func viewWillAppear(_ animated: Bool) {
    navigationController?.navigationBar.isHidden = true
    super.viewWillAppear(animated)
}


override func viewWillDisappear(_ animated: Bool) {
    if (navigationController?.topViewController != self) {
        navigationController?.navigationBar.isHidden = false
    }
    super.viewWillDisappear(animated)
}

Ответ 6

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

Вместо этого @Chad M. стратегия использования UINavigationControllerDelegate является хорошей, и вот более полное решение. Шаги:

  • Подкласс UINavigationController
  • Внедрить метод -navigationController:willShowViewController:animated для отображения или скрытия панели навигации в зависимости от того, отображает ли она контроллер корневого представления
  • Отмените методы инициализации, чтобы установить подкласс UINavigationController в качестве своего собственного делегата.

Полный код для этого решения можно найти в this Gist. Здесь реализация navigationController:willShowViewController:animated:

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    /* Hide navigation bar if root controller */
    if ([viewController isEqual:[self.viewControllers firstObject]]) {
        [self setNavigationBarHidden:YES animated:animated];
    } else {
        [self setNavigationBarHidden:NO animated:animated];
    }
}

Ответ 7

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

Вот как я заработал.

Шаг 1 - У меня есть изображение и пользовательские краны на этом изображении один раз. Я фиксирую этот жест и вставляю его в новый imageViewController, его в imageViewController, я хочу иметь полноэкранное изображение.

- (void)handleSingleTap:(UIGestureRecognizer *)gestureRecognizer {  
NSLog(@"Single tap");
ImageViewController *imageViewController =
[[ImageViewController alloc] initWithNibName:@"ImageViewController" bundle:nil];

godImageViewController.imgName  = // pass the image.
godImageViewController.hidesBottomBarWhenPushed=YES;// This is important to note. 

[self.navigationController pushViewController:godImageViewController animated:YES];
// If I remove the line below, then I get this error. [CALayer retain]: message sent to deallocated instance . 
// [godImageViewController release];
} 

Шаг 2 - Все эти шаги ниже приведены в ImageViewController

Шаг 2.1 - В ViewDidLoad отобразите navBar

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
NSLog(@"viewDidLoad");
[[self navigationController] setNavigationBarHidden:NO animated:YES];
}

Шаг 2.2 - В viewDidAppear настройте задачу таймера с задержкой (я установил ее на 1 с). И после задержки добавьте эффект затухания. Я использую alpha для использования затухания.

- (void)viewDidAppear:(BOOL)animated
{
NSLog(@"viewDidAppear");

myTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self     selector:@selector(fadeScreen) userInfo:nil repeats:NO];
}

- (void)fadeScreen
{
[UIView beginAnimations:nil context:nil]; // begins animation block
[UIView setAnimationDuration:1.95];        // sets animation duration
self.navigationController.navigationBar.alpha = 0.0;       // Fades the alpha channel of   this view to "0.0" over the animationDuration of "0.75" seconds
[UIView commitAnimations];   // commits the animation block.  This Block is done.
}

Шаг 2.3 - Под viewWillAppear добавьте жест SingleTap к изображению и сделайте navBar полупрозрачным.

- (void) viewWillAppear:(BOOL)animated
{

NSLog(@"viewWillAppear");


NSString *path = [[NSBundle mainBundle] pathForResource:self.imgName ofType:@"png"];

UIImage *theImage = [UIImage imageWithContentsOfFile:path];

self.imgView.image = theImage;

// add tap gestures 
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];  
[self.imgView addGestureRecognizer:singleTap];  
[singleTap release];  

// to make the image go full screen
self.navigationController.navigationBar.translucent=YES;
}

- (void)handleTap:(UIGestureRecognizer *)gestureRecognizer 
{ 
 NSLog(@"Handle Single tap");
 [self finishedFading];
  // fade again. You can choose to skip this can add a bool, if you want to fade again when user taps again. 
 myTimer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self  selector:@selector(fadeScreen) userInfo:nil repeats:NO];
 }

Шаг 3 - Наконец, в viewWillDisappear, обязательно верните все вещи

- (void)viewWillDisappear: (BOOL)animated 
{ 
self.hidesBottomBarWhenPushed = NO; 
self.navigationController.navigationBar.translucent=NO;

if (self.navigationController.topViewController != self)
{
    [self.navigationController setNavigationBarHidden:NO animated:animated];
}

[super viewWillDisappear:animated];
}

Ответ 8

В случае, если у кого-то все еще возникают проблемы с быстрой обратной связью, отменил ошибку, поскольку @fabb прокомментировал принятый ответ.

Мне удалось исправить это, переопределив viewDidLayoutSubviews, в дополнение к viewWillAppear/viewWillDisappear, как показано ниже:

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    self.navigationController?.setNavigationBarHidden(false, animated: animated)
}

override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)
    self.navigationController?.setNavigationBarHidden(true, animated: animated)
}

//*** This is required to fix navigation bar forever disappear on fast backswipe bug.
override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    self.navigationController?.setNavigationBarHidden(false, animated: false)
}

В моем случае я замечаю, что это связано с тем, что контроллер корневого представления (где скрыт nav) и контроллер перемещенного представления (отображается nav). имеет разные стили строки состояния (например, темный и светлый). В тот момент, когда вы запускаете backswipe для вызова контроллера вида, появится дополнительная цветная анимация состояния. Если вы отпустите палец, чтобы отменить интерактивную поп, , пока анимация строки состояния не завершена, панель навигации навсегда исчезла!

Однако эта ошибка не возникает, если стили строки состояния обоих контроллеров представлений одинаковы.

Ответ 9

Если вы хотите скрыть панель навигации полностью в контроллере, гораздо более чистое решение в корневом контроллере должно иметь что-то вроде:

@implementation MainViewController
- (void)viewDidLoad {
    self.navigationController.navigationBarHidden=YES;
    //...extra code on view load  
}

Когда вы нажимаете дочерний вид в контроллере, панель навигации остается скрытой; если вы хотите отобразить его только в дочернем элементе, вы добавите код для отображения it(self.navigationController.navigationBarHidden=NO;) в обратном вызове viewWillAppear и аналогичным образом код для его скрытия на viewWillDisappear

Ответ 10

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

- (void)viewWillAppear:(BOOL)animated {
    [self.navigationController setToolbarHidden:YES/NO animated:animated];
    [super viewWillAppear:animated];
}

Ответ 11

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

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

и отобразите навигационную панель, когда пользователь покинет эту страницу, это будет viewWillDisappear

- (void)viewWillDisappear:(BOOL)animated {
    [self.navigationController setNavigationBarHidden:NO animated:YES];
    [super viewWillDisappear:animated];
}

Ответ 12

Простой Swift 3 совместимый ответ: Используйте segue и представляйте его в порядке. Это соответствует Apple Documentation. https://developer.apple.com/library/content/documentation/WindowsViews/Conceptual/ViewControllerCatalog/Chapters/NavigationControllers.html

Пример: Контроллер страницы входа → Контроллер навигации → Создать новый контроллер учетной записи (с кнопкой "Назад", которая ссылается на страницу входа через страницу, которая представляет собой модно)

При обращении к другой странице, на которой вы не хотите, чтобы панель навигации отображалась, создайте на этой странице сегмент, в этом примере присоедините его к кнопке "Назад" и перетащите его на страницу входа в систему, но выберите "Показывать по-настоящему", Это можно сделать из Main.storyboard.

Не требуется кодирование!

Ответ 13

Скрытие панели навигации только на первой странице может быть достигнуто и с помощью раскадровки. На раскадровке, навигационная панель навигации навигации → панель навигации. И выберите свойство "Скрыто" в инспекторе атрибутов. Это скроет навигационную панель, начиная с первого контроллера просмотра, пока не станет видимым для требуемого диспетчера представлений.

Навигационная панель может быть восстановлена ​​до видимого в обратном вызове ViewController ViewWillAppear.

-(void)viewWillAppear:(BOOL)animated {

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

Ответ 14

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

- (UIStatusBarStyle)preferredStatusBarStyle{
    return UIStatusBarStyleLightContent;
}

Я нашел странное решение, которое, если вы установите стиль строки состояния UIStatusBarStyleLightContent для каждого viewControllers вашего navigationController, панель навигации будет работать так, как ожидалось.