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

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

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

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

enter image description here

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


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

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


ВАЖНО

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

4b9b3361

Ответ 1

Основная проблема заключается в MMDrawerController. Если вы вникнете в него, вы найдете много методов, связанных со статусом, таких как setShowsStatusBarBackgroundView setStatusBarViewBackgroundColor и многое другое. Что-то в их коде подталкивает представление вверх, когда панель состояния скрыта.

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

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

enter image description here

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

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

Edit:

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

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

Взято из здесь

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

Ответ 2

Я не знаю, будет ли это решить вашу проблему, но я получил почти такой же эффект, используя проект 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, которая устанавливает центр .y, не обращаясь к скучной части установки фреймов.

Ответ 3

Вот как вы должны сделать это в 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

Ответ 4

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

https://developer.apple.com/library/ios/DOCUMENTATION/UIKit/Reference/UIApplication_Class/Reference/Reference.html#//apple_ref/occ/instm/UIApplication/setStatusBarHidden:withAnimation:

Ответ 5

Вы можете использовать -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];
    }
}

enter image description here