Подтвердить что ты не робот

Как заставить панель навигации в 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];
    

но это не работает.

Любая помощь оценивается. Благодаря

4b9b3361

Ответ 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];
}

Я только что протестировал это с существующим проектом, и он сработал.