Как скрыть строку состояния, не скрывая ее

Разработчики iOS наверняка знают о проблеме со строкой состояния и знаменитым "слайдом / гамбургером / ящиком". Проблема хорошо объяснена здесь: http://uxmag.com/articles/adapting-ui-to-ios-7-the-side-menu

Я использую библиотеку MMDrawerController, и у нее есть приятный хак, который позволяет нам создать фиктивную строку состояния прямо над контроллером представления контейнера. К сожалению, это не очень хорошо работает. Какие новости? Новость заключается в том, что я наткнулся на приложение ( Tinder), которое идеально решает эту проблему. Я создал GIF, который отлично показывает, что делает Tinder.

Вам нужно подождать несколько секунд, чтобы увидеть гифку, потому что в ней есть ошибка, и я не знаю, как от нее избавиться. Просто подождите одну / две секунды, и вы сможете правильно увидеть GIF.


Во всяком случае, что делает Tinder? Когда пользователь нажимает на верхнюю левую кнопку меню и начинает смахивать вправо, строка состояния аккуратно исчезает. И когда представление вернется в исходное положение, строка состояния появится снова.

Я и счастлив, и немного расстроен из-за этого, потому что это означает, что должен быть способ сделать это, но я действительно не знаю, как реализовать это (возможно, взлом MMDrawerController). Любая помощь будет высоко ценится.


ВАЖНЫЙ

Пожалуйста, обратите внимание на то, что метод setStatusBarHidden: будет полностью скрывать строку состояния, это означает, что весь вид имеет высоту -20px. Это, очевидно, не решение, потому что, как видно из рисунка, изображение не растягивается.

5 ответов

Решение

Ваша главная проблема с MMDrawerController, Если вы покопаетесь в нем, вы найдете множество методов, связанных со статусной строкой, таких как setShowsStatusBarBackgroundViewsetStatusBarViewBackgroundColor и больше. Что-то в их коде увеличивает представление, когда строка состояния скрыта.

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

Вот простой способ сделать это:

введите описание изображения здесь

ViewControllerA:

-(BOOL)prefersStatusBarHidden
{
    return _hidden;
}
- (void)statusHide
{
    [UIView animateWithDuration:0.4 animations:^() {[self setNeedsStatusBarAppearanceUpdate];
    }completion:^(BOOL finished){}];
}

ViewControllerB: (Контейнер в ViewControllerA)

- (IBAction)move:(UIButton *)sender
{
    parent = (ViewController*)self.parentViewController;
    parent.hidden = !parent.hidden;
    CGRect frame = parent.blueContainer.frame;
    if(parent.hidden)
    {
        frame.origin.x = 150;
    }
    else
    {
        frame.origin.x = 0;
    }

    [UIView animateWithDuration:1 animations:^() {parent.blueContainer.frame = frame;}completion:^(BOOL finished){}];
    [parent statusHide];
}

Для совместимости с iOS 6 используйте:

[[UIApplication sharedApplication] setStatusBarHidden:_hidden withAnimation:UIStatusBarAnimationFade];

Представление таблицы и другие подпредставления останутся на своих местах и ​​не будут перемещены вверх.

Редактировать:

Добавление панели навигации:

UINavigationController изменит высоту своего UINavigationBar до 44 или 64 точек, в зависимости от довольно странного и недокументированного набора ограничений. Если UINavigationController обнаруживает, что вершина фрейма его вида визуально соприкасается с вершиной его UIWindow, то он рисует свою панель навигации с высотой 64 точки. Если его вершина не соприкасается с вершиной окна UIWindow (даже если она отклонена только на одну точку), то она рисует свою навигационную панель "традиционным" способом с высотой 44 точки. Эта логика выполняется UINavigationController, даже если в иерархии контроллера представления вашего приложения есть несколько дочерних элементов. Нет способа предотвратить такое поведение.

Взято отсюда

Вы могли бы очень просто подкласс UINavigationController и создайте свой собственный navbar, чтобы избежать этой досады.

Я не знаю, решит ли это вашу проблему, но я получил почти такой же эффект, используя проект SWRevealViewController. В appDelegate я установил метод делегата из этого класса, чтобы сделать это:

- (void)revealController:(SWRevealViewController *)revealController willMoveToPosition:(FrontViewPosition)position {
#ifdef DEBUG
    NSArray *teste = @[@"FrontViewPositionLeftSideMostRemoved",@"FrontViewPositionLeftSideMost",@"FrontViewPositionLeftSide",@"FrontViewPositionLeft",@"FrontViewPositionRight",@"FrontViewPositionRightMost",@"FrontViewPositionRightMostRemoved"];
    NSLog(@"%@ %d", teste[position], position);
#endif
    if (position == FrontViewPositionRight)
        [[UIApplication sharedApplication] setStatusBarHidden:YES  withAnimation:UIStatusBarAnimationFade];
    UINavigationController *frontViewController = (id)revealController.frontViewController;
    frontViewController.navigationBar.centerY += (position == FrontViewPositionRight) ?  20 : 0; //  20 == statusbar heihgt
}

- (void)revealController:(SWRevealViewController *)revealController didMoveToPosition:(FrontViewPosition)position {
    if (position == FrontViewPositionLeft)
        [[UIApplication sharedApplication] setStatusBarHidden:NO  withAnimation:UIStatusBarAnimationFade];
}

centerY - это категория в UIView, которая устанавливает center.y, не занимаясь скучной частью установки переменных кадра.

Вот как вы должны сделать это в iOS 7:

@implementation ViewController
{
    BOOL _hideStatusBar;
}

-(UIStatusBarStyle)preferredStatusBarStyle
{
    return UIStatusBarStyleDefault;
}

-(UIStatusBarAnimation)preferredStatusBarUpdateAnimation
{
    return UIStatusBarAnimationFade;
}

-(BOOL)prefersStatusBarHidden
{
    return _hideStatusBar;
}

-(void)setStatusBarHidden:(BOOL)hidden
{
    [UIView animateWithDuration:1.0 animations:^{
        _hideStatusBar = hidden;
        [self setNeedsStatusBarAppearanceUpdate];
    }];
}

@end

Вы можете использовать -setStatusBarHidden:withAnimation: если вы отрегулируете свои рамки просмотра в -viewDidAppear:, то вы не увидите никакого натяжения. Обратите внимание, что автоматическое расположение отключено.

-(void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    CGRect frame = self.view.frame;
    // adjust root view frame 
    frame.origin.y -= 20;
    frame.size.height += 20;

    [self.view setFrame:frame];

    // adjust subviews y position
    for (UIView *subview in [self.view subviews])
    {
        CGRect frame = subview.frame;
        frame.origin.y += 20;
        [subview setFrame:frame];
    }
}

- (IBAction)sliderChanged:(id)sender
{
    UISlider *s = (UISlider *)sender;
    if (s.value > .5)
    {
        UIApplication *app = [UIApplication sharedApplication];
        if (![app isStatusBarHidden])
            [app setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade];
    }
    else
    {
        UIApplication *app = [UIApplication sharedApplication];
        if ([app isStatusBarHidden])
            [app setStatusBarHidden:NO withAnimation:UIStatusBarAnimationFade];
    }
}

введите описание изображения здесь

Проверьте метод setStatusBarHidden:withAnimation: на UIApplication, Это позволит вам показать или скрыть строку состояния, и анимация может быть ни одна, исчезать или слайд. Вам просто нужно добавить вызов, чтобы скрыть панель, и один, чтобы показать панель в правильное время, и решить, нравится ли вам затухание, как показано на рисунке, или слайд работает лучше для вас.

https://developer.apple.com/library/ios/DOCUMENTATION/UIKit/Reference/UIApplication_Class/Reference/Reference.html:

Другие вопросы по тегам