Как одновременно вставить / вывести статус-бар и панель навигации? - PullRequest
4 голосов
/ 28 июня 2010

Я бы хотел показать и скрыть панель состояния и панель навигации одновременно, используя эффект слайда.

Вот как я пытался:

[[UIApplication sharedApplication] setStatusBarHidden:hide withAnimation:UIStatusBarAnimationSlide];
[self.navigationController setNavigationBarHidden:hide animated:animated];

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

Ответы [ 7 ]

5 голосов
/ 22 февраля 2012

Ответ ios-lizard - почти то, что я хотел, но навигационная панель появляется снова при повороте устройства, если hidden не установлен правильно.Для меня это сработало:

Скрытие анимации работает / выглядит хорошо ДА !!мы больше не видим пробелов. :D)

- (void)toggleFullscreen {

    UINavigationBar *navBar = self.navigationController.navigationBar;
    CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
    float animationDuration;
    if(statusBarFrame.size.height > 20) { // in-call
        animationDuration = 0.5;
    } else { // normal status bar 
        animationDuration = 0.6;
    }

    _fullscreen = !_fullscreen;
    if (_fullscreen) { 
        // Change to fullscreen mode
        // Hide status bar and navigation bar
        [[UIApplication sharedApplication] setStatusBarHidden:YES
                                                withAnimation:UIStatusBarAnimationSlide];
        [UIView animateWithDuration:animationDuration animations:^{
            navBar.frame = CGRectMake(navBar.frame.origin.x,
                                  -navBar.frame.size.height,
                                  navBar.frame.size.width,
                                  navBar.frame.size.height);
        } completion:^(BOOL finished) {
            [self.navigationController setNavigationBarHidden:YES animated:NO];
        }];

    } else {
        // Change to regular mode
        // Show status bar and navigation bar
        [[UIApplication sharedApplication] setStatusBarHidden:NO
                                                withAnimation:UIStatusBarAnimationSlide];
        [UIView animateWithDuration:animationDuration animations:^{
             navBar.frame = CGRectMake(navBar.frame.origin.x,
                                       statusBarFrame.size.height,
                                       navBar.frame.size.width,
                                       navBar.frame.size.height);
        } completion:^(BOOL finished) {
            [self.navigationController setNavigationBarHidden:NO animated:NO];
        }];

    }

}
2 голосов
/ 20 января 2012

Так я исправил эту проблему для своего приложения.

    CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];

    // delta is the amount by which the nav bar will be moved
    delta = statusBarFrame.size.height + self.navigationController.navigationBar.frame.size.height;

    if(statusBarFrame.size.height>20) { // in-call
        animationDuration = 0.5;
    }
    else { // normal status bar 
        animationDuration = 0.6;
    }

    // hide status bar
    [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];

    // hide nav bar
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:animationDuration];

    self.navigationController.navigationBar.frame = CGRectOffset(self.navigationController.navigationBar.frame, 0.0, -delta);

    [UIView commitAnimations];
1 голос
/ 25 февраля 2016

Ответ nacho4d - почти то, что я хотел. Но он меняет фрейм navBar до того, как будет виден navBar.Таким образом, мы не можем видеть анимацию перехода. Похоже, что NavBar появляются внезапно.Более того, при показе statusBarFrame.size.height равен 0. Вот его код:

[[UIApplication sharedApplication] setStatusBarHidden:NO
                                            withAnimation:UIStatusBarAnimationSlide];
    [UIView animateWithDuration:animationDuration animations:^{
         navBar.frame = CGRectMake(navBar.frame.origin.x,
                                   statusBarFrame.size.height,
                                   navBar.frame.size.width,
                                   navBar.frame.size.height);
    } completion:^(BOOL finished) {
        [self.navigationController setNavigationBarHidden:NO animated:NO];
    }];

при показе, мы хотели бы, чтобы строка состояния скользила с помощью панели навигации. вот мой ответ :

        UINavigationBar *navBar = self.navigationController.navigationBar;
        [[UIApplication sharedApplication] setStatusBarHidden:hidden withAnimation:UIStatusBarAnimationSlide];

        [UIView animateWithDuration:0.35 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
            // make navigationBar visual
            if (!hidden)
            {
                [self.navigationController setNavigationBarHidden:hidden animated:NO];
            }

            navBar.frame = CGRectMake(navBar.frame.origin.x,
                                      hidden ? -navBar.frame.size.height : 20,
                                      navBar.frame.size.width,
                                      navBar.frame.size.height);
        } completion:^(BOOL finished) {
            if (hidden)
            {
                [self.navigationController setNavigationBarHidden:hidden animated:NO];
            }
        }];
  1. при скрытии, а скрытый равен NO .мы должны сначала изменить фрейм navBar, а затем скрыть navBar.
  2. при отображении, а hidden , равный YES .мы сначала делаем navBar визуальным, затем меняем фрейм.
  3. выбираем UIViewAnimationOptionCurveEaseOut , чтобы он выглядел лучше.
1 голос
/ 30 апреля 2013

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

Обратите внимание, что navigationBar - это выход, а statusBarHeight - переменная экземпляра с плавающей точкой.

- (IBAction)toggleControls:(id)sender {
    BOOL isHidden = ! [UIApplication sharedApplication].statusBarHidden;
    if (isHidden)
        statusBarHeight = [UIApplication sharedApplication].statusBarFrame.size.height;
    [UIView animateWithDuration:[UIApplication sharedApplication].statusBarOrientationAnimationDuration animations:^{
        self.navigationBar.frame = CGRectMake(self.navigationBar.frame.origin.x,
                                              isHidden ? -self.navigationBar.frame.size.height : statusBarHeight,
                                              self.navigationBar.frame.size.width,
                                              self.navigationBar.frame.size.height);
    }];
    [[UIApplication sharedApplication] setStatusBarHidden:isHidden withAnimation:UIStatusBarAnimationSlide];
}
1 голос
/ 14 января 2011

Очевидно, что нет простого решения сделать это правильно.Apple должна исправить это .

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

0 голосов
/ 21 августа 2014

Вы можете использовать переменную экземпляра для этого:

self.navigationController setNavigationBarHidden:hide animated:animated];
_shouldHideStatusBar = hide;

И реализовать следующую функцию:

- (BOOL)prefersStatusBarHidden{
    return _shouldHideStatusBar;
}

setNavigationBarHidden: анимированная функция автоматически вызовет prefersStatusBarHidden функцию. Если это не так, вы можете вызвать его с помощью следующего метода UIViewController:

[self setNeedsStatusBarAppearanceUpdate];

И, конечно, вы можете выбрать свой стиль анимации скрытия строки состояния с помощью:

- (UIStatusBarAnimation) preferredStatusBarUpdateAnimation {
    return UIStatusBarAnimationSlide;
}
0 голосов
/ 05 октября 2010

Это не очень хороший ответ, но он работает.Итак, что я сделал:

// This method gets called by whatever action you want

- (void) toggleShowStatusNavBars:(id)sender {

    // Assuming you have a ivar called barsHidden

    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:0.4]; // This is IMPORTANT, 0.4s

    self.navigationController.navigationBar.alpha = (barsHidden?1.0:0.0);  

    barsHidden = !barsHidden; 

    [UIView setAnimationDelegate:self];
    [UIView setAnimationWillStartSelector:@selector(setStatusBarHidden)];

    [UIView commitAnimations];
}

- (void) setStatusBarHidden {
    [[UIApplication sharedApplication] setStatusBarHidden:barsHidden animated:YES];
}

Это в основном синхронизирует начало анимации (так как вы вызываете setStatusBarHidden в начале анимации панели навигации. Ключевая часть заключается в том, что анимация строки состояниякажется, занимает 0,4 секунды.

Это работает для меня, но если вы найдете лучший способ, постите здесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...