для iPhone скрыть панель навигации только на первой странице
У меня есть код ниже, который скрывает и показывает навигационную панель. Он скрыт, когда загружается первый вид, а затем скрыт, когда вызываются "дети". Проблема в том, что я не могу найти событие/действие, чтобы вызвать его, чтобы скрыть снова, когда они возвращаются к корневому представлению....
У меня есть кнопка" Тест " на корневой странице, которая вручную выполняет действие, но это не очень красиво, и я хочу, чтобы это было автоматически.
-(void)hideBar
{
self.navController.navigationBarHidden = YES;
}
-(void)showBar
{
self.navController.navigationBarHidden = NO;
}
14 ответов:
самое приятное решение, которое я нашел, это сделать следующее в первый вид-контроллер.
С
- (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]; }Свифт
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реализация этих методов, и в соответствии с документацией вы должны вызвать реализацию супер где-то в вашей реализации.
другой подход, который я нашел, это установить делегат для
NavigationController:navigationController.delegate = self;и использовать
setNavigationBarHiddenнаnavigationController:willShowViewController:animated:- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated { // Hide the nav bar if going home. BOOL hide = viewController != homeViewController; [navigationController setNavigationBarHidden:hide animated:animated]; }простой способ настроить поведение для каждого
ViewControllerвсе в одном месте.
Я бы поставил код в viewWillAppear делегат на каждом представлении были показаны:
Как это, где вам нужно, чтобы скрыть это:
- (void)viewWillAppear:(BOOL)animated { [yourObject hideBar]; }Как это, где вы должны показать это:
- (void)viewWillAppear:(BOOL)animated { [yourObject showBar]; }
одна небольшая настройка, которую я должен был сделать на других ответах, - это только отобразить панель в viewWillDisappear, если причина ее исчезновения связана с тем, что на нее нажимается навигационный элемент. Это потому, что вид может исчезнуть по другим причинам.
поэтому я только показываю панель, если этот вид больше не является самым верхним видом:
- (void) viewWillDisappear:(BOOL)animated { if (self.navigationController.topViewController != self) { [self.navigationController setNavigationBarHidden:NO animated:animated]; } [super viewWillDisappear:animated]; }
в 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) }
принятый в настоящее время ответ не соответствует предполагаемому поведению, описанному в вопросе. Вопрос требует, чтобы панель навигации была скрыта на корневом контроллере вида, но видна везде, но принятый ответ скрывает панель навигации на определенном контроллере вида. Что происходит, когда другой экземпляр первого контроллера вида помещается в стек? Он скроет панель навигации, даже если мы не смотрим на корневой вид контроллер.
вместо этого, @Chad M.'s стратегия использовать
UINavigationControllerDelegateхорошая, а вот более полное решение. Шаги:
- подкласс
UINavigationController- реализовать
-navigationController:willShowViewController:animatedметод, чтобы показать или скрыть панель навигации на основе того, показывает ли он корневой контроллер вида- переопределите методы инициализации, чтобы установить подкласс UINavigationController в качестве собственного делегата
полный код для этого решения можно найти в в этом суть. Вот это
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-у меня есть изображение и пользователь нажимает на это изображение однажды. Я ловлю этот жест и толкаю его в новый
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-In
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 к изображению и сделайте навигационную панель полупрозрачной.- (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]; }
в случае, если у кого-то все еще есть проблемы с быстрая обратная связь отменена ошибка как прокомментировал @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 для того чтобы хлопнуть регулятор взгляда, там будет дополнительная анимация цвета строки состояния. Если вы отпустите палец, чтобы отменить интерактивный поп,пока анимация строки состояния не закончена панель навигации-это навсегда!
однако эта ошибка не возникает, если стили строки состояния обоих контроллеров представления одинаковы.
если то, что вы хотите, чтобы скрыть панель навигации полностью в контроллере, гораздо более чистым решением является, в корневом контроллере, есть что-то вроде:
@implementation MainViewController - (void)viewDidLoad { self.navigationController.navigationBarHidden=YES; //...extra code on view load }при нажатии дочернего представления в контроллере панель навигации останется скрытой; если вы хотите отобразить ее только в дочернем представлении, вы добавите код для отображения
it(self.navigationController.navigationBarHidden=NO;)наviewWillAppearобратный вызов, и аналогично код для его скрытия наviewWillDisappear
отдаю должное @chad-m 'S ответ.
вот версия Swift:
- создать новый файл
MyNavigationController.swift
import UIKit class MyNavigationController: UINavigationController, UINavigationControllerDelegate { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. self.delegate = self } func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) { if viewController == self.viewControllers.first { self.setNavigationBarHidden(true, animated: animated) } else { self.setNavigationBarHidden(false, animated: animated) } } }разница между ответом чада-м и моим:
наследовать от UINavigationController, так что вы не будете засорять свой rootViewController.
использовать
self.viewControllers.first, а неhomeViewController, Так что вы не будете делать это 100 раз для ваших 100 UINavigationControllers в 1 раскадровке.
самая простая реализация может заключаться в том, чтобы каждый контроллер представления указывал, скрыта ли его навигационная панель или нет в его
viewWillAppear:animated:метод. Тот же подход хорошо работает для скрытия/отображения панели инструментов:- (void)viewWillAppear:(BOOL)animated { [self.navigationController setToolbarHidden:YES/NO animated:animated]; [super viewWillAppear:animated]; }
скрытие панели навигации только на первой странице может быть достигнуто с помощью раскадровки, а также. На раскадровке, Гото Сцена Навигационного Контроллера - > Панель Навигации. И выберите 'скрытый С атрибуты инспектора. Это скроет панель навигации, начиная с первого viewcontroller, пока она не станет видимой для требуемого viewcontroller.
панель навигации можно установить обратно в видимое в ViewWillAppear ViewController обратный звонок.
-(void)viewWillAppear:(BOOL)animated { [self.navigationController setNavigationBarHidden:YES animated:animated]; [super viewWillAppear:animated]; }
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) }
путем реализации этого кода в вашем 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]; }

Comments