Как заставить панель навигации в UINavigationController обновлять свою позицию, когда строка состояния скрыта?
У меня есть UINavigationController
с видимой панелью навигации.
У меня есть один конкретный UIViewController
, который я хотел бы скрыть строку состояния при нажатии в стек навигации. Как только этот viewController выскочил, я хотел бы снова показать строку состояния.
Я скрываю панель в методе viewWillAppear
моего UIViewController
следующим образом:
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.navigationController setWantsFullScreenLayout:YES];
[[UIApplication sharedApplication] setStatusBarHidden:YES animated:YES];
}
Заметьте, что я устанавливаю setWantsFullScreenLayout:YES
здесь для ясности, но на самом деле я просто устанавливаю это свойство в Interface Builder.
Проблема:
Панель навигации NavigationController не перемещается вверх, чтобы занять пространство скрытой строки состояния.
Хакерное решение
Единственное, что я нашел, которое работало, чтобы обновить позицию навигационной панели, было скрыть ее и показать ее снова, например:
[[UIApplication sharedApplication] setStatusBarHidden:YES animated:YES];
[self.navigationController setNavigationBarHidden:YES animated:NO];
[self.navigationController setNavigationBarHidden:NO animated:NO];
но это явно взломать, там должен быть лучший способ.
Другие вещи, которые я пробовал:
-
Я попытался вызвать [super viewWillAppear]
после скрытия строки состояния, то есть в конце моего метода.
-
Я попробовал setNeedsLayout на navigationController.view вот так:
[[UIApplication sharedApplication] setStatusBarHidden:YES animated:YES];
[self.navigationController.view setNeedsLayout];
но это не работает.
Любая помощь оценивается.
Благодаря
Ответы
Ответ 1
Существует два способа сделать то, что вы просите.
Один из них - это перемещение панели навигации вручную:
В представленииWillAppear:
[UIApplication sharedApplication].statusBarHidden = YES;
self.view.frame = [UIScreen mainScreen].applicationFrame;
CGRect frame = self.navigationController.navigationBar.frame;
frame.origin.y = 0;
self.navigationController.navigationBar.frame = frame;
В представленииWillDisappear:
[UIApplication sharedApplication].statusBarHidden = NO;
CGRect frame = self.navigationController.navigationBar.frame;
frame.origin.y = 20.0;
self.navigationController.navigationBar.frame = frame;
Все будет хорошо, если вы тоже захотите отключить навигационную панель, хотя я подозреваю, что это не то, что вы хотели:
[UIApplication sharedApplication].statusBarHidden = YES;
self.navigationController.navigationBarHidden = YES;
Ответ 2
Вам следует попробовать изменить размер рамки вашего UIViewControllers's
после того, как вы скрыли StatusBar. ApplicationFrame обновляет его origin.y и size.height во время метода setStatusBarHidden:animated:
.
CGRect rect = [UIScreen mainScreen].applicationFrame;
self.view.frame = rect;
[self.view setNeedsLayout];
Ответ 3
Я нашел, что приведенные выше решения не совсем сработали, когда представление находится в середине анимационной презентации, поэтому я отложил скрытие строки состояния следующим образом:
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// doesn't work immediately because modal view has to finish loading
dispatch_async(dispatch_get_main_queue(), ^(){
[[UIApplication sharedApplication] setStatusBarHidden:YES];
self.view.frame = [UIScreen mainScreen].applicationFrame;
});
}
Ответ 4
В контроллере корневого представления (где вы хотите показать строку состояния):
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[UIApplication sharedApplication] setStatusBarHidden:NO animated:YES];;
}
В контроллере представления вы нажимаете на стек (где вы хотите скрыть строку состояния):
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[UIApplication sharedApplication] setStatusBarHidden:YES animated:YES];;
}
Edit:
Я понимаю, что вы хотите скрыть строку состояния. Они перепутали их с тех пор, как вы показывали/скрывали навигационную панель в коде, который вы опубликовали. Виноват. Во всяком случае, это по сути тот же код:
В контроллере корневого представления (где вы хотите показать строку состояния):
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[UIApplication sharedApplication] setStatusBarHidden:NO animated:YES];
}
В контроллере представления вы нажимаете на стек (где вы хотите скрыть строку состояния):
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[UIApplication sharedApplication] setStatusBarHidden:YES animated:YES];
}
Я только что протестировал это с существующим проектом, и он сработал.