2009-05-10 2 views
339

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

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

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

ответ

966

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

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 «s из этих методов, а также в соответствии с документацией вы должны вызвать выполнение супер где-то в вашей реализации.

+27

Это фантастический фрагмент кода. – kim3er

+1

Это полностью скалы! Я боролся с этим хотя бы на день. Благодаря!!! –

+0

Я думал, что рамка будет меняться, но до тех пор, пока viewDidAppear: :(Так что если вам нужен точный кадр после скрытия навигации, это не решение. –

17

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

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

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

как это, где вам нужно показать это:

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

Ли, если это исправить вашу проблему, отметьте Pablo как «решение». –

+2

Единственная проблема заключается в том, что панель навигации «всплывает» и отображается при перемещении с одного взгляда на другой. Возможно ли, чтобы навигационная панель не была на первом изображении, и когда второе представление скользит на место, оно имеет навигационную панель без каких-либо всплывающих окон? – Henning

+2

@henning Чтобы сделать вкладку NavBar вставкой/выводом, как и следовало ожидать, вам нужно использовать setNavigationBarHidden: animated :. См. Ниже ответ Алана Роджерса (который действительно должен быть отмечен как «решение»). –

1

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

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

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

16

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

Так я только отобразите панель, если эта точка зрения уже не самый верхний вид:

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

    [super viewWillDisappear:animated]; 
} 
+3

+1, вы _usually_ не хотите показывать панель навигации при нажатии модального диалога. –

30

Другой подход, который я нашел, чтобы установить делегата для 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 всего в одном месте.

+1

Я думаю, что это лучший ответ. это работает отлично. – binnyb

+0

Это правильный ответ. –

+0

Когда это вызвано? –

0

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

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

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

6

После нескольких испытаний здесь, как я получил это работает на то, что я хотел. Вот что я пытался. - У меня есть изображение с изображением. и я хотел, чтобы изображение отображалось на весь экран. - У меня есть контроллер навигации с 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 с). И после задержки добавьте эффект замирания. Я использую альфа, чтобы использовать затухание.

- (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]; 
} 
9

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

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

  1. Подкласс UINavigationController
  2. Реализуйте метод -navigationController:willShowViewController:animated, чтобы показать или скрыть панель навигации в зависимости от того, что показывает контроллер представления корневой
  3. Переопределить методы инициализации для установки подкласса 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]; 
    } 
} 
+1

Это более подходящий ответ, чем принятый. –

13

в 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) 
} 
+0

Не могли бы вы объяснить, почему вы проверяете! = Self? – Kitson

+2

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

+0

Кажется, что если вы используете 'navcontroller.navagationBarHidden', он сломает весь навигационный контроллер (без прокрутки вперед и назад). Чтобы заставить его работать, вместо этого я использовал 'navigationController ?.navigationBar.hidden'. Swiping все еще работает, и он не оставляет пустого пространства, потому что он, кажется, находится в стеке или что-то – Sirens

3

В случае, если кто по-прежнему возникают проблемы с быстро backswipe отмененного ошибка, как @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) 
} 

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

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

0

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

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

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

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

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

Пример: Войти Страница Controller -> Навигационный контроллер -> Создание контроллера новой учетной записи (с задней кнопки, что ссылки на странице входа в систему с помощью Segue, который представляет модально)

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

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

0

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

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

-(void)viewWillAppear:(BOOL)animated { 

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

Swift 4:

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

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) 
} 
Смежные вопросы