Панель состояния iOS 7 возвращается к стилю iOS 6 по умолчанию в приложении iPhone?

В iOS 7 UIStatusBar был спроектирован таким образом, что он сливается с представлением следующим образом:

GUI designed by Tina Tavčar (GUI, разработанный Тина Тавчар)

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

  • Есть ли простое решение (например, установка свойства в info.plist), которое может изменить способ работы [не перекрываться] до того, как он находится в iOS6?

  • Я знаю, что более простое решение состоит в том, чтобы иметь self.view.center.x + 20 пунктов для каждого отдельного контроллера вида, но их изменение приведет к другим измерениям вверх (наличие другого self.view.center.x может вызвать проблемы в пользовательских сегментах и ​​т.д..) и вдруг это превращается в утомительную работу, которой лучше всего избежать.

  • Я действительно буду рад, если кто-то может предоставить мне однострочное решение для этого.

P.S. Я знаю, что могу скрыть строку состояния, выполняя такие действия, как

[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];

В методе didFinishLaunchingWithOptions, но обходной путь - это сокращение, избегающее проблемы, поэтому я не считаю это реальным решением.

Ответ 1

Отправлено через сообщение в блоге, которое я написал, но здесь приведено полное описание строк состояния, навигационных панелей и контроллеров контейнеров на iOS 7:

  • Невозможно сохранить макет строки состояния стиля iOS 6. Строка состояния всегда будет перекрывать ваше приложение на iOS 7

  • Не путайте появление строки состояния со строкой строки состояния. Внешний вид (свет или значение по умолчанию) не влияет на то, как выкладывается строка состояния (рамка/высота/перекрытие). Важно также отметить, что в строке состояния системы больше нет цвета фона. Когда API ссылается на UIStatusBarStyleLightContent, они означают белый текст на четком фоне. UIStatusBarStyleDefault - черный текст на четком фоне.

  • Внешний вид строки управления управляется одним из двух взаимоисключающих базовых путей: вы можете либо установить их программно традиционным способом, либо UIKit обновит внешний вид для вас на основе некоторых новых свойств UIViewController. Последний вариант включен по умолчанию. Проверьте значение plist приложения для "Внешний вид строки на панели ViewController", чтобы узнать, какой из них вы используете. Если вы установите для этого значения значение YES, каждый контроллер верхнего уровня в вашем приложении (отличном от стандартного контроллера представления контейнера UIKit) должен переопределить preferredStatusBarStyle, возвращая либо стиль по умолчанию, либо стиль света. Если вы измените значение plist на NO, тогда вы можете управлять появлением строки состояния, используя известные методы UIApplication.

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

  • Если вы создаете фоновое изображение пользовательской навигационной панели, высота которого составляет всего 44 точки (88 пикселей), а границы представлений UINavigationControllers соответствуют границам UIWindows (как описано в № 4), UINavigationController рисует ваше изображение в (0,20,320,44), оставляя 20 точек непрозрачного черного пространства над вашим пользовательским изображением. Это может смутить вас в том, что вы умный разработчик, который обошел правило №1, но вы ошибаетесь. Навигационная панель по-прежнему на 64 пункта. Вложение UINavigationController в иерархию представления стиля слайда для раскрытия делает это совершенно ясным.

  • Остерегайтесь правдоподобных свойств edgeForExtendedLayout UIViewController. Регулировка edgeForExtendedLayout ничего не делает в большинстве случаев. Единственный способ, которым UIKit использует это свойство, - это добавить контроллер представления в UINavigationController, тогда UINavigationController использует edgeForExtendedLayout, чтобы определить, должен ли его контроллер просмотра дочерних элементов быть видимым под областью панели навигации/состояния. Настройка edgeForExtendedLayout на UINavigationController сама по себе не делает ничего, чтобы изменить, имеет ли UINavigationController 44-битовую или 64-очную большую область навигационной панели. См. № 4 для этой логики. Подобная логика компоновки применяется к нижней части вашего представления при использовании панели инструментов или UITabBarController.

  • Если все, что вы пытаетесь сделать, это запретить вашему настраиваемому контроллеру детского представления скрывать панель навигации внутри UINavigationController, а затем установить edgeForExtendedLayout в UIRectEdgeNone (или, по крайней мере, маску, исключающую UIRectEdgeTop). Установите это значение как можно раньше в жизненном цикле вашего контроллера вида.

  • UINavigationController и UITabBarController также будут пытаться вставлять contentInsets представления таблиц и представления коллекции в свою иерархию подзадач. Он делает это аналогично логике строки состояния из # 4. Существует программный способ предотвращения этого, установив autoAdjustsScrollViewInsets в НЕТ для представлений таблиц и представлений коллекции (по умолчанию это значение YES). Это создавало серьезные проблемы для Whisper и Riposte, поскольку мы используем корректировки contentInset для управления компоновкой представлений таблиц в ответ на изменения панели инструментов и клавиатуры.

  • Повторить: нет способа вернуться в логику компоновки строки стиля iOS 6. Чтобы приблизиться к этому, вы должны переместить все контроллеры представлений вашего приложения в представление контейнера, которое смещено на 20 пунктов от верхней части экрана, оставляя намеренно черный вид за панель состояния, чтобы имитировать старый вид. Это метод, который мы использовали в Riposte и Whisper.

  • Apple прилагает все усилия, чтобы убедиться, что вы не пытаетесь сделать # 9. Они хотят, чтобы мы перепроектировали все наши приложения, чтобы подкрыть панель состояния. Однако есть много убедительных аргументов, как для пользователей, так и для технических причин, почему это не всегда хорошая идея. Вы должны делать то, что лучше для ваших пользователей, а не просто следовать прихотью платформы.

Ответ 2

Обновления 19 сентября 2013 года:

исправлены ошибки масштабирования путем добавления self.window.bounds = CGRectMake(0, 20, self.window.frame.size.width, self.window.frame.size.height);

исправленные опечатки в операторе NSNotificationCenter


Обновления 12 сентября 2013 года:

исправлено UIViewControllerBasedStatusBarAppearance до NO

добавлено решение для приложений с поворотом экрана

добавлен подход для изменения цвета фона в строке состояния.


По-видимому, нет способа вернуть строку состояния iOS7 обратно к тому, как она работает в iOS6.

Однако мы всегда можем написать некоторые коды и превратить строку состояния в iOS6-like, и это самый короткий способ, с помощью которого я могу придумать:

  • Установите UIViewControllerBasedStatusBarAppearance в NO в info.plist (Чтобы отказаться от того, чтобы контроллеры представлений настраивали стиль строки состояния, чтобы мы могли установить стиль строки состояния с помощью метода UIApplicationstatusBarStyle.)

  • В AppDelegate application:didFinishLaunchingWithOptions вызовите

    if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) {
        [application setStatusBarStyle:UIStatusBarStyleLightContent];
        self.window.clipsToBounds =YES;
        self.window.frame =  CGRectMake(0,20,self.window.frame.size.width,self.window.frame.size.height-20);
    
        //Added on 19th Sep 2013
        self.window.bounds = CGRectMake(0, 20, self.window.frame.size.width, self.window.frame.size.height);
    }
    return YES;
    


чтобы:

  • Проверьте, не iOS 7.

  • Задайте содержимое строки состояния белым, в отличие от UIStatusBarStyleDefault.

  • Избегайте subviews, чьи рамки выходят за пределы видимых границ (чтобы представления отображались в главном представлении сверху).

  • Создайте иллюзию, что строка состояния занимает пробел, например, как в iOS 6, сдвигая и изменяя размер окна окна приложения.


Для приложений с вращением экрана

используйте NSNotificationCenter для определения изменений ориентации, добавив

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationDidChangeStatusBarOrientation:)
name:UIApplicationDidChangeStatusBarOrientationNotification
object:nil];

в if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) и создайте новый метод в AppDelegate:

- (void)applicationDidChangeStatusBarOrientation:(NSNotification *)notification
{
    int a = [[notification.userInfo objectForKey: UIApplicationStatusBarOrientationUserInfoKey] intValue];
    int w = [[UIScreen mainScreen] bounds].size.width;
    int h = [[UIScreen mainScreen] bounds].size.height;
    switch(a){
        case 4:
            self.window.frame =  CGRectMake(0,20,w,h);
            break;
        case 3:
            self.window.frame =  CGRectMake(-20,0,w-20,h+20);
            break;
        case 2:
            self.window.frame =  CGRectMake(0,-20,w,h);
            break;
        case 1:
           self.window.frame =  CGRectMake(20,0,w-20,h+20);
    }
}

Таким образом, при изменении ориентации он выведет оператор switch для определения ориентации экрана приложения (Portrait, Upside Down, Landscape Left или Landscape Right) и изменит окно окна приложения соответственно, чтобы создать иллюзию состояния строки iOS 6.


Чтобы изменить цвет фона в строке состояния:

Добавить

 @property (retain, nonatomic) UIWindow *background;

в AppDelegate.h, чтобы сделать background свойство в вашем классе и предотвратить ARC от его освобождения. (Вам не нужно делать это, если вы не используете ARC.)

После этого вам просто нужно создать UIWindow в if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1):

background = [[UIWindow alloc] initWithFrame: CGRectMake(0, 0, self.window.frame.size.width, 20)];
background.backgroundColor =[UIColor redColor];
[background setHidden:NO];

Не забывайте @synthesize background; после @implementation AppDelegate!

Ответ 3

ОБНОВЛЕНИЕ (НОВОЕ РЕШЕНИЕ)

Это обновление является лучшим решением проблемы с навигационной панелью iOS 7. Вы можете указать пример цвета панели навигации: FakeNavBar.backgroundColor = [UIColor redColor];

Примечание. Если вы используете контроллер навигации по умолчанию, используйте старое решение.

AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

    if(NSFoundationVersionNumber >= NSFoundationVersionNumber_iOS_7_0)
    {
        UIView *FakeNavBar = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 20)];
        FakeNavBar.backgroundColor = [UIColor whiteColor];

        float navBarHeight = 20.0;
        for (UIView *subView in self.window.subviews) {

            if ([subView isKindOfClass:[UIScrollView class]]) {
                subView.frame = CGRectMake(subView.frame.origin.x, subView.frame.origin.y + navBarHeight, subView.frame.size.width, subView.frame.size.height - navBarHeight);
            } else {
                subView.frame = CGRectMake(subView.frame.origin.x, subView.frame.origin.y + navBarHeight, subView.frame.size.width, subView.frame.size.height);
            }
        }
        [self.window addSubview:FakeNavBar];
    }

    return YES;

}

OLD SOLUTION - Если вы используете предыдущий код, пожалуйста, проигнорируйте следующий код и изображение

Это старая версия решения для навигационной панели iOS 7.

Я решил проблему со следующим кодом. Это для добавления строки состояния. didFinishLaunchingWithOptionsдел >

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
    UIView *addStatusBar = [[UIView alloc] init];
    addStatusBar.frame = CGRectMake(0, 0, 320, 20);
    addStatusBar.backgroundColor = [UIColor colorWithRed:0.973 green:0.973 blue:0.973 alpha:1]; //change this to match your navigation bar
    [self.window.rootViewController.view addSubview:addStatusBar];
}

И для Interface Builder это происходит, когда вы открываете с iOS 6; он начинается с 0 пикселей.

Примечание: iOS 6/7 Deltas отображаются только в том случае, если вы снимите флажок "Использовать автозапуск" для контроллера просмотра в "Инспекторе файлов" (самый левый значок) на панели сведений.

Enter image description here

Ответ 4

РЕШЕНИЕ:

Установите его в своем контроллере viewview или в rootviewcontroller, переопределив метод:

-(BOOL) prefersStatusBarHidden
    {
        return YES;
    }

Ответ 5

Вот еще один подход к проектам, которые широко используют раскадровку:

ЗАДАЧА:

Цель этого подхода - воссоздать тот же стиль строки состояния в iOS7, что и в iOS6 (см. заголовок вопроса "Панель состояния iOS 7 Вернуться к стилю iOS 6?" ).

РЕЗЮМЕ:

Для этого мы используем раскадровку как можно больше, перемещая элементы пользовательского интерфейса, которые перекрываются строкой состояния (под iOS 7) вниз, и используя дельта, чтобы отменить изменение формата вниз для iOS 6.1 или ранее. Получающееся в результате дополнительное пространство в iOS 7 занято UIView, а backgroundColor - цветом нашего выбора. Последний может быть создан в коде или с помощью раскадровки (см. Ниже АЛЬТЕРНАТИВЫ)

Предположения:

Чтобы получить желаемый результат, следуя приведенным ниже шагам, предполагается, что View controller-based status bar appearance установлено в NO и что ваш Status bar style либо установлен на "Прозрачный черный стиль (альфа 0,5)", либо "Непрозрачный черный стиль" ". Обе настройки можно найти или добавить в разделе" Информация" в настройках вашего проекта.

ШАГОВ:

  • Добавьте подпрограмму в UIWindow, чтобы служить фоном состояния. Для этого добавьте следующее в AppDelegate application: didFinishLaunchingWithOptions: после makeKeyAndVisible

    if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) {
        UIView *statusBarBackgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, yourAppsUIWindow.frame.size.width, 20)];
        statusBarBackgroundView.backgroundColor = [UIColor blackColor];
        [yourAppsUIWindow addSubview:statusBarBackgroundView];
    }
    
  • Так как вы программно добавили фон для iOS 7 ТОЛЬКО, вам нужно будет отрегулировать расположение элементов интерфейса, которые перекрываются в строке состояния соответственно, сохраняя при этом свой макет для iOS6. Для этого выполните следующие действия:

    • Убедитесь, что Use Autolayout не установлен для вашей раскадровки (это связано с тем, что иначе "iOS 6/7 Deltas" не отображается в инспекторе размеров). Сделать это:
      • выберите файл раскадровки
      • Показать Утилиты
      • выберите "Показать инспектор файлов"
      • В разделе "Document Builder Document" снимите флажок "Использовать автоспуск"
    • При необходимости, чтобы помочь вам отслеживать изменения макета для iOS 7 и 6 при их применении, выберите "Редактор помощников", выберите "Предварительный просмотр" и "iOS 6.1 или более ранняя версия": enter image description hereenter image description here
    • Теперь выберите элемент пользовательского интерфейса, который вы хотите настроить, чтобы он больше не перекрывался строкой состояния.
    • Выберите "Показать инспектор размера" в столбце "Утилиты"
    • Переместите элемент пользовательского интерфейса вдоль оси Y на ту же величину, что и строка состояния bg height: enter image description here
    • И измените значение Delta для iOS6/7 для Y с помощью той же НЕГАТИВНОЙ суммы, что и высота строки состояния bg (обратите внимание на изменение предварительного просмотра iOS 6, если вы его используете): enter image description here

АЛЬТЕРНАТИВНЫЕ:

Чтобы добавить еще меньше кода в тяжелые проекты с раскадрой и иметь автозапуск фона в строке состояния, вместо того, чтобы программно добавлять фон для вашей панели статусов, вы можете добавить цветное представление к каждому контроллеру представления, который находится на самой вершине упомянутого диспетчера просмотров основной вид. Затем вы изменили бы дельта высоты этого нового представления на ту же отрицательную величину, что и высота вашего представления (чтобы он исчез в iOS 6).

Недостатком этой альтернативы (хотя, возможно, и незначительной с учетом совместимости с авторотатом) является тот факт, что этот дополнительный вид не сразу отображается, если вы просматриваете свою раскадровку для iOS 6. Вы только знаете, что это там, если бы вы посмотрели в разделе "Структура документа" раскадровки.

Ответ 6

Если вы не хотите, чтобы ваши контроллеры отображались на панели состояния (и на панели навигации), снимите флажок "Расширить края в верхних барах" в Конструктор интерфейсов в Xcode 5.

Uncheck the Extend Edges Under Top Bars

Ответ 8

Я рассмотрел много и много многих и многих учебников, чтобы исправить эту проблему. Но никто из них не работает! Вот мое решение, и оно работает для меня:

if( [[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0f ) {
    float statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;
    for( UIView *v in [self.view subviews] ) {
        CGRect rect = v.frame;
        rect.origin.y += statusBarHeight;
        v.frame = rect;
    }
}

Логика проста. Я перемещаю все виды детей на self.view с 20 пикселями. Все это. Затем скриншот будет отображаться так же, как и iOS 6. Я ненавижу строку состояния iOS7! ~ "~

Ответ 9

Небольшая альтернатива Арчи Холту, немного более простая:

а. Установите

UIViewControllerBasedStatusBarAppearance to NO in info.plist

б. В AppDelegate application:didFinishLaunchingWithOptions: вызовите:

if ([[UIDevice currentDevice].systemVersion floatValue] < 7)
{
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
}
else
{
    // handling statusBar (iOS7)
    application.statusBarStyle = UIStatusBarStyleLightContent;
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
    self.window.clipsToBounds = YES;

    // handling screen rotations for statusBar (iOS7)
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidChangeStatusBarOrientationNotification:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
}

И добавьте метод:

- (void)applicationDidChangeStatusBarOrientationNotification:(NSNotification *)notification
{
    // handling statusBar (iOS7)
    self.window.frame = [UIScreen mainScreen].applicationFrame;
}

Вы также можете рассмотреть подклассу UIWindow для обработки самого UIApplicationDidChangeStatusBarOrientationNotification.

Ответ 10

Я использовал это во всех контроллерах моего представления, это просто. Добавьте эти строки во все ваши методы viewDidLoad:

- (void)viewDidLoad{
    //add this 2 lines:
    if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
        self.edgesForExtendedLayout = UIRectEdgeNone;

    [super viewDidLoad];
}

Ответ 11

Попробуйте этот простой метод....

Шаг 1. Чтобы изменить в одиночном viewController

[[UIApplication sharedApplication] setStatusBarStyle: UIStatusBarStyleBlackOpaque];

Шаг 2: изменение всего приложения

info.plist
      ----> Status Bar Style
                  --->UIStatusBarStyle to UIStatusBarStyleBlackOpaque

Шаг 3. Также добавьте это в каждый viewWillAppear, чтобы отрегулировать высоту statusbar для iOS7

    [[UIApplication sharedApplication]setStatusBarStyle:UIStatusBarStyleLightContent];
    if ([[UIDevice currentDevice].systemVersion floatValue] >= 7) {
        CGRect frame = [UIScreen mainScreen].bounds;
        frame.origin.y+=20.0;
        frame.size.height-= 20.0;
        self.view.frame = frame;
        [self.view layoutIfNeeded];
    }

Ответ 12

В конструкторе интерфейсов есть опция, которая вызывает свойство Delta iOS 6/7, которое направлено на решение проблемы смещения.

Взгляните на него в вопросе Interface Builder: что такое UIView Layout iOS 6/7 Deltas для?.

Ответ 13

Я получил строку состояния, такую ​​как iOS 6 в iOS 7.

Установите UIViewControllerBasedStatusBarAppearance в NO в info.plist

Введите этот код в - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions метод

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
    [application setStatusBarStyle:UIStatusBarStyleLightContent];
    self.window.clipsToBounds =YES;
    self.window.frame =  CGRectMake(0,20,self.window.frame.size.width,self.window.frame.size.height);

    //Added on 19th Sep 2013
    NSLog(@"%f",self.window.frame.size.height);
    self.window.bounds = CGRectMake(0,0, self.window.frame.size.width, self.window.frame.size.height);
}

Он может сбрасывать все ваши взгляды на 20 пикселей. Для этого используется следующий код в -(void)viewDidAppear:(BOOL)animated методе

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
    CGRect frame=self.view.frame;
    if (frame.size.height==[[NSUserDefaults standardUserDefaults] floatForKey:@"windowHeight"])
    {
        frame.size.height-=20;
    }
    self.view.frame=frame;
}

Вы должны установить значение параметра WindowHeight Userdefaults после выделения окна в методе didFinishLauncing, например

self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[[NSUserDefaults standardUserDefaults] setFloat:self.window.frame.size.height forKey:@"windowHeight"];

Ответ 14

Если вы используете построитель интерфейса, попробуйте следующее:

В вашем файле xib:

1) Выберите основной вид, установите цвет фона в черный (или любой цвет, который вы хотите, чтобы строка состояния была

2) Убедитесь, что фон представляет собой автономный подзаголовок, расположенный как дочерний элемент верхнего уровня в виде контроллера.
Переместите свой фон, чтобы стать прямым дочерним элементом представления контроллера. Проверьте панель автосохранения, чтобы убедиться, что вы заблокировали все края кадра, активировали обе оси гибкости, и если это UIImageView, установите для режима содержимого значение Масштаб. Программно это означает, что contentMode установлен в UIViewContentModeScaleToFill и имеет маску автоматического изменения размера, установленную на (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight).

3) Теперь переместите все, что заблокировано сверху вниз на 20 очков, и установите iOS 6/7 delta Y на -20.
Все дети верхнего уровня, которые привязаны к верхнему кадру на панели автосохранения, должны быть сдвинуты на 20 пунктов, а их iOS 6/7 delta Y установлены на -20. (Cmd выберите все из них и нажмите стрелку вниз 20 раз - есть ли лучший способ?)

4) Отрегулируйте высоту деления iOS 6/7 всех вышеперечисленных элементов с гибкой высотой. Любой элемент, который был заблокирован для верхнего и нижнего фрейма и имел гибкую высоту, включенную на панели автосохранения, также должен иметь дельта-высоту iOS 6/7, установленную на 20. Это включает в себя фоновый вид, упомянутый выше. Это может показаться антиинтуитивным, но из-за порядка, в котором они применяются, это необходимо. Высота кадра устанавливается сначала (на основе устройства), затем применяются дельта, и, наконец, маски аутозации применяются на основе смещения всех дочерних кадров - подумайте об этом немного, это будет иметь смысл.

5) Наконец, элементы, которые были заблокированы в нижнем фрейме, но не в верхнем кадре, вообще не нуждаются в дельтах.

Это даст вам идентичную строку состояния в iOS7 и iOS6.

С другой стороны, если вы хотите стилизовать iOS7 при сохранении совместимости с iOS6, установите для значений высоты дельты Y/delta значение 0 для фонового представления.

Чтобы увидеть больше информации о миграции iOS7, прочитайте полный пост: http://uncompiled.blogspot.com/2013/09/legacy-compatible-offsets-in-ios7.html

Ответ 15

Моим решением было добавить UIView с высотой 20 точек поверх окна, когда на iOS 7. Затем я создал метод в классе AppDelegate, чтобы показать/скрыть "твердый" фон состояния. В application:didFinishLaunchingWithOptions::

// ...

// Add a status bar background
self.statusBarBackground = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.window.bounds.size.width, 20.0f)];
self.statusBarBackground.backgroundColor = [UIColor blackColor];
self.statusBarBackground.alpha = 0.0;
self.statusBarBackground.userInteractionEnabled = NO;
self.statusBarBackground.layer.zPosition = 999; // Position its layer over all other views
[self.window addSubview:self.statusBarBackground];

// ...
return YES;

Затем я создал метод, чтобы затухать в/из черного фона строки состояния:

- (void) showSolidStatusBar:(BOOL) solidStatusBar
{
    [UIView animateWithDuration:0.3f animations:^{
        if(solidStatusBar)
        {
            [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
            self.statusBarBackground.alpha = 1.0f;
        }
        else
        {
            [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
            self.statusBarBackground.alpha = 0.0f;
        }
    }];
}

Все, что мне нужно сделать, это вызов [appDelegate showSolidStatusBar:YES] при необходимости.

Ответ 16

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

Я закончил писать метод утилиты в классе Utility и вызвал его со всех контроллеров представления viewDidLayoutSubviews Method.

+ (void)addStatusBarIfiOS7:(UIViewController *)vc
    {
        if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) {
            CGRect viewFrame = vc.view.frame;
            if(viewFrame.origin.y == 20) {
                //If the view y origin is already 20 then don't move it down.
                return;
            }
            viewFrame.origin.y+=20.0;
            viewFrame.size.height-= 20.0;
            vc.view.frame = viewFrame;
            [vc.view layoutIfNeeded];
        }
    }

Переопределите метод viewDidLayoutSubviews в контроллере представления, где вы хотите строку состояния. Это приведет вас к бремени Autolayout.

- (void)viewDidLayoutSubviews
{
    [[UIApplication sharedApplication]setStatusBarStyle:UIStatusBarStyleLightContent];
    [super viewDidLayoutSubviews];
    [MyUtilityClass addStatusBarIfiOS7:self];
}

Ответ 17

Самый простой способ сделать это - установить более старый SDK на ваш новейший Xcode.

Как установить старый SDK на новейший Xcode?

  • U может получить SDK iOS 6.1 из http://www.4shared.com/zip/NlPgsxz6/iPhoneOS61sdk.html или загрузить старый Xcode и получить SDK из его содержимого

  • Разархивируйте и вставьте эту папку в /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs

  • Перезагрузите xcode.

  • U теперь может выбрать более старый SDK для ваших настроек сборки проекта.

Надеюсь, это поможет вам. Это сработало для меня =)

Ответ 18

Как использование presentViewController:animated:completion: испорченного window.rootViewController.view, мне пришлось найти другой подход к этой проблеме. Я, наконец, получил его для работы с модалами и вращениями путем подкласса UIView моего rootViewController.

.h

@interface RootView : UIView

@end

.m

@implementation RootView

-(void)setFrame:(CGRect)frame
{
    if (self.superview && self.superview != self.window)
    {
        frame = self.superview.bounds;
        frame.origin.y += 20.f;
        frame.size.height -= 20.f;
    }
    else
    {
        frame = [UIScreen mainScreen].applicationFrame;
    }

    [super setFrame:frame];
}

- (void)layoutSubviews
{
    self.frame = self.frame;

    [super layoutSubviews];
}

@end

Теперь у вас есть сильное обходное решение для анимации iOS7.

Ответ 19

Я опоздал на этот ответ, но я просто хочу поделиться тем, что я сделал, что в основном самое легкое решение

Прежде всего- > Перейдите к файлу info.plist и добавить стиль строки состояния → Прозрачный черный стиль (альфа 0,5)

Теперь, здесь он идет: -

Добавьте этот код в свой AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
     //Whatever your code goes here
  if(kDeviceiPad){

     //adding status bar for IOS7 ipad
         if (IS_IOS7) {
              UIView *addStatusBar = [[UIView alloc] init];
              addStatusBar.frame = CGRectMake(0, 0, 1024, 20);
              addStatusBar.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:1]; //change this to match your navigation bar
              [self.window.rootViewController.view addSubview:addStatusBar];
                    }
                }
    else{

         //adding status bar for IOS7 iphone
        if (IS_IOS7) {
            UIView *addStatusBar = [[UIView alloc] init];
            addStatusBar.frame = CGRectMake(0, 0, 320, 20);
            addStatusBar.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:1]; //You can give your own color pattern
            [self.window.rootViewController.view addSubview:addStatusBar];
        }

    return YES;
   }

Ответ 20

Скрыть строку состояния можно. Таким образом, ваше приложение будет полноэкранным. Я думаю, что лучшее, что вы получите.

UIStatusBarStyleNone или установить целевые настройки.

Ответ 21

Мое очень простое решение (при условии, что поддерживается только вертикальная ориентация) - это переопределить границы окон приложений для версий iOS ниже 7, в деле делегирования делегата didFinishLaunchingWithOptions:

CGRect screenBounds = [[UIScreen mainScreen] bounds];
if ([HMService getIOSVersion] < 7) {
    // handling statusBar (iOS6) by leaving top 20px for statusbar.
    screenBounds.origin.y = 20;
    self.window = [[UIWindow alloc] initWithFrame:screenBounds];
}
else {
    self.window = [[UIWindow alloc] initWithFrame:screenBounds];
}

Ответ 22

Шаги для скрытия строки состояния в iOS 7:

1.Вобходимо к файлу info.plist вашего приложения.

2.And Set, Просмотреть вид строки состояния на основе контроллера: Boolean NO

Надеюсь, я решил проблему с баром состояния.....

Ответ 23

Чтобы продолжить работу с setStatusBarHidden: я использую эту категорию:

@interface UIApplication (StatusBar)

-(void)setIOS7StatusBarHidden:(BOOL)statusBarHidden;

@end

@implementation UIApplication (StatusBar)

-(void)setIOS7StatusBarHidden:(BOOL)statusBarHidden{
    if (!IOS7) {
        [self setStatusBarHidden:statusBarHidden];
        return;
     }

    if ([self isStatusBarHidden] == statusBarHidden) {
        return;
    }

    [self setStatusBarHidden:statusBarHidden];
    [self keyWindow].clipsToBounds = YES;
    CGFloat offset = statusBarHidden ? 0 : 20;
    [self keyWindow].frame =  CGRectMake(0,offset,[self keyWindow].frame.size.width,[self keyWindow].frame.size.height-offset);
    [self keyWindow].bounds = CGRectMake(0, offset, [self keyWindow].frame.size.width,[self keyWindow].frame.size.height);
}

@end

Ответ 24

Я нашел здесь лучшие альтернативы и решение для этой проблемы с навигационной панелью в iOS7!

http://www.appcoda.com/customize-navigation-status-bar-ios-7/

Я надеюсь, что это очистит все наши вопросы и тревоги.

Ответ 25

Это может быть слишком поздно, чтобы поделиться, но у меня есть что-то, что может помочь кому-то, я пытался подклассифицировать UINavigationBar и хотел, чтобы он выглядел как ios 6 с черным статусом и текстом строки состояния в белом.

Вот что я нашел для этого

        self.navigationController?.navigationBar.clipsToBounds = true
        self.navigationController?.navigationBar.translucent = false
        self.navigationController?.navigationBar.barStyle = .Black
        self.navigationController?.navigationBar.barTintColor = UIColor.whiteColor()

Это сделало мой фоновый индикатор состояния черным, текст строки состояния белым и белым цветом панели навигации.

iOS 9.3, XCode 7.3.1