4

Я хотел бы показывать и скрывать statusBar и navigationBar одновременно, используя эффект слайда.Как включить/выключить статусBar и navigationBar одновременно?

Это, как я попробовал:

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

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

+0

Я подал сообщение об ошибке с Apple: http://openradar.appspot.com/8548087 Пожалуйста, обманите его, если вы тоже пострадали. –

ответ

1

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

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

0

Это не очень важный ответ, но он работает. Так что я сделал это:

// 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. секунд.

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

+0

Вы скрываете navBar, используя альфа-замирание. Это проще, потому что в этом случае вы можете напрямую манипулировать navBar. В скользящем случае меня интересует, что это не жизнеспособный подход, так как navigationController также манипулирует рамкой просмотра контента. –

2

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

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]; 
5

КСН-ящерицы почти то, что я хотел, но навигационная панель снова появляется при повороте устройства, если hidden не установлено правильно. Так что это сработало для меня:

Hidding animating works/выглядит красиво YEAH !!.

Отображение анимации в порядке, (я хотел бы сделать строку состояния слайд с панели навигации, но по крайней мере мы не видим пробелов больше. :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]; 
     }]; 

    } 

} 
1

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

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

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

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

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

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

- (BOOL)prefersStatusBarHidden{ 
    return _shouldHideStatusBar; 
} 

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

[self setNeedsStatusBarAppearanceUpdate]; 

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

- (UIStatusBarAnimation) preferredStatusBarUpdateAnimation { 
    return UIStatusBarAnimationSlide; 
} 
1

ответ 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. когда Hidding и скрытого равного NO. мы должны сначала сменить рамку navBar, а затем скрыть navBar.
  2. при показе, и скрыто, равное ДА. сначала делаем navBar визуальным, затем меняем рамку.
  3. мы выбираем UIViewAnimationOptionCurveEaseOut, чтобы он выглядел лучше.