iOS 7 - строка состояния перекрывает вид


109

У меня ViewControllerесть внутри UINavigationcontroller, но панель навигации скрыта. Когда я запускаю приложение на iOS 7, строка состояния отображается поверх моего представления. Есть ли способ избежать этого?

Я не хочу писать код для конкретной ОС.

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

Я попытался установить View controller-based status bar appearanceзначение NO, но это не помогло.


Я опубликовал свой ответ, чтобы отобразить строку состояния, такую ​​как iOS 6, в iOS 7 stackoverflow.com/questions/18294872/…
Desert Rose

2
Вам также необходимо настроить исходное значение y и значение дельты, чтобы справиться с проблемой строки состояния. Это может помочь вам stackoverflow.com/q/18980925/1545180
Ganapathy

Ответы:


95

Xcode 5 iOS 6/7 Deltasспециально создан для решения этой проблемы. В раскадровке я переместил свои представления на 20 пикселей вниз, чтобы они выглядели прямо на iOS 7, и, чтобы сделать его совместимым с iOS 6, я изменил Delta yна -20.

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

Поскольку моя раскадровка не использует автоматическую компоновку, для правильного изменения высоты представлений в iOS 6 мне пришлось установить Delta heightтакже Delta Y.


8
ваш ответ правильный, но он не работает с дисплеем 4 ". Обновите свой ответ, если вы можете заставить его работать и для дисплея 4". Заранее спасибо.

2
@AnkitMehta Мне не нужно было делать ничего особенного для 4-
дюймовых айфонов

5
работал у меня. Обратите внимание, что для того, чтобы увидеть эти дельты, вы должны отменить выбор «Использовать автоматическое размещение» в разделе «Идентификация и тип» для раскадровки.
marsant 03 окт.13,

2
Я обнаружил, что помимо установки -20 для ∆Y, мне также пришлось установить +20 для ∆Height
Толанд Хон

3
Что произойдет, если изменится высота строки состояния? Например: когда пользователь активирует точку доступа и т. Д., Тогда высота 40 пикселей ...
Лукаш

69

Если вам просто НЕ нужна строка состояния, вам нужно обновить свой список следующими данными: Для этого в список добавьте эти 2 параметра:

<key>UIStatusBarHidden</key>
<true/>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>

Ожидается, что в iOS 7 вы создадите свое приложение с учетом наложенной прозрачной строки состояния. См., Например, новое приложение «Погода» для iOS 7.


3
На самом деле это единственный хороший ответ, поскольку он решает проблему в своей основе так, как это было задумано. Итак: нужны положительные голоса!
eleven59, 04

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

1
@ eleven59, вы имеете в виду то, что задумали автократы в Apple.
JohnK

1
Определенно это лучше, чем изменение смещения контроллера представления (которое кажется действительно грязным).
Бенджамин Оман

скрывать строку состояния - не лучшая идея ... Я знаю, что это самый простой способ справиться с iOS 7, но НЕОБХОДИМО время ...
Фахим Паркар

43

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

Если у вас есть UIViewControllerвнутри a UINavigationControllerи отображается навигационная панель, у вас может быть следующий код в вашем viewDidLoadили фоновое изображение для navigationBar.

self.edgesForExtendedLayout = UIRectEdgeNone;

Если у вас скрыта панель навигации, вам необходимо настроить все элементы UIView, сдвинув 20 точек. Другого решения не вижу. Немного поможет использование автоматической раскладки.

Вот пример кода для определения версии iOS, если вы хотите обеспечить обратную совместимость.

NSUInteger DeviceSystemMajorVersion() {
    static NSUInteger _deviceSystemMajorVersion = -1;
    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{
        NSString *systemVersion = [UIDevice currentDevice].systemVersion;
        _deviceSystemMajorVersion = [[systemVersion componentsSeparatedByString:@"."][0] intValue];
    });

   return _deviceSystemMajorVersion;
}

18
Вместо получения, анализа и сравнения версии системы рекомендуется использоватьif ([self respondsToSelector:@selector(edgesForExtendedLayout)])
Себастьян Ходжас

15

Единственное рабочее решение, которое я сделал сам.

Вот мой подкласс UIViewController https://github.com/comonitos/ios7_overlaping

1 подкласс от UIViewController

2 Создайте подкласс вашего window.rootViewController от этого класса.

3 Вуаля!

- (void) viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
        CGRect screen = [[UIScreen mainScreen] bounds];
        if (self.navigationController) {
            CGRect frame = self.navigationController.view.frame;
            frame.origin.y = 20;
            frame.size.height = screen.size.height - 20;
            self.navigationController.view.frame = frame;
        } else {
            if ([self respondsToSelector: @selector(containerView)]) {
                UIView *containerView = (UIView *)[self performSelector: @selector(containerView)];

                CGRect frame = containerView.frame;
                frame.origin.y = 20;
                frame.size.height = screen.size.height - 20;
                containerView.frame = frame;
            } else {
                CGRect frame = self.view.frame;
                frame.origin.y = 20;
                frame.size.height = screen.size.height - 20;
                self.view.frame = frame;
            }
        }
    }
}

4 Добавьте это, чтобы ваша строка состояния стала белой Сразу после [self.window makeKeyAndVisible]; !!!

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}

но это не показывает время наверху ... Самый большой недостаток ... :(
Фахим Паркар

Отлично работает, но для шага 4 вы должны использовать предпочтительныйStatusBarStyle в своем контроллере представления, так как setStatusBarStyle устарел, и его действие по умолчанию - ничего не делать. stackoverflow.com/a/19014724/1192732
CpnCrunch

13
-(UIStatusBarStyle)preferredStatusBarStyle
{
    return UIStatusBarStyleLightContent;
}

-(void)viewWillLayoutSubviews{

 if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) 
  {
    self.view.clipsToBounds = YES;
    CGRect screenRect = [[UIScreen mainScreen] bounds];
    CGFloat screenHeight = 0.0;
    if(UIDeviceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]))
        screenHeight = screenRect.size.height;
    else
        screenHeight = screenRect.size.width;
    CGRect screenFrame = CGRectMake(0, 20, self.view.frame.size.width,screenHeight-20);
    CGRect viewFrame1 = [self.view convertRect:self.view.frame toView:nil];
    if (!CGRectEqualToRect(screenFrame, viewFrame1))
    {
        self.view.frame = screenFrame;
        self.view.bounds = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
    }
  }
}

Добавить ключ в список --- Просмотр появления строки состояния на основе контроллера: НЕТ


при необходимости изменить цвет окна
Даршит Шах

Спасибо, это решило мою проблему с перекрытием. Но одна проблема все еще существует - Просмотр внешнего вида строки состояния на основе контроллера: Я думаю, НЕТ, чтобы скрыть строку состояния. Но когда я устанавливаю его на ДА, тогда он не показывает строку состояния, а когда я устанавливаю его на НЕТ, он показывает строку состояния. Так что, пожалуйста, скажите мне, я ошибаюсь в концепции или как?
Nayan

1
Я думаю, потому что возьмите полупрозрачный цвет по умолчанию, установленный в didFinishLaunchingWithOptions 'self.window.backgroundColor = [UIColor blueColor];' и установить в plist Просмотр
отображения

Приятное спасибо! Кроме того, просто хочу отметить, что в документации Apple рекомендуется проверять с помощью if (NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_6_1) {} else {}. Ура!
Джоэл Балмер

Большое вам спасибо. Ваш код очень полезен для нас. Пожалуйста, расскажите о функции viewWillLayoutSubviews.
user3182143

4

Чтобы скрыть строку состояния в ios7, выполните следующие простые шаги:

В Xcode Resourcesперейдите в папку " " и откройте " (app name)-Info.plist file".

  • проверьте " View controller based status bar appearance" ключ и установите его значение " NO"
  • проверьте " Status bar is initially hidden" ключ и установите его значение " YES"

Если ключей нет, вы можете добавить его, выбрав « information property list» вверху и щелкнув значок +


Прочтите вопрос четко, он не просил полностью скрыть строку состояния.
ShayanK

1
@AspersionCast: Он спросил: "Есть ли способ избежать этого?" и это один из способов избежать этого.
Мандип Пасбола


3

При использовании xibs очень простой реализацией является инкапсуляция всех подпредставлений внутри представления контейнера с помощью флагов изменения размера (которые вы уже будете использовать для совместимости с 3,5 и 4 дюймами), чтобы иерархия представлений выглядела примерно так

xib иерархия

а затем viewDidLoadсделайте что-то вроде этого:

- (void)viewDidLoad
{
  [super viewDidLoad];
  // initializations
  if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) // only for iOS 7 and above
  {
    CGRect frame = containerView.frame;
    frame.origin.y += 20;
    frame.size.height -= 20;
    containerView.frame = frame;
  }
}

Таким образом, нет необходимости изменять наконечники для совместимости с iOS 7. Если у вас есть фон, его можно оставить снаружи containerViewи позволить ему покрыть весь экран.



2

Для панели навигации:

Написание этого кода:

self.navigationController.navigationBar.translucent = NO;

только что помогло мне.


1

Ответ Винсента EdgeForExtendedLayout работал у меня.

Эти макросы помогают определить версию ОС, облегчая задачу

// 7.0 and above 
#define IS_DEVICE_RUNNING_IOS_7_AND_ABOVE() ([[[UIDevice currentDevice] systemVersion] compare:@"7.0" options:NSNumericSearch] != NSOrderedAscending) 

// 6.0, 6.0.x, 6.1, 6.1.x
#define IS_DEVICE_RUNNING_IOS_6_OR_BELOW() ([[[UIDevice currentDevice] systemVersion] compare:@"6.2" options:NSNumericSearch] != NSOrderedDescending) 

добавьте эти макросы в файл prefix.pch вашего проекта, и они будут доступны где угодно

if(IS_DEVICE_RUNNING_IOS_7_AND_ABOVE())
{
 //some iOS 7 stuff
 self.edgesForExtendedLayout = UIRectEdgeNone;
}

if(IS_DEVICE_RUNNING_IOS_6_OR_BELOW())
{
 // some old iOS stuff
}

1
для меня self.edgesForExtendedLayout = UIRectEdgeNone; не работает ... по какой причине?
Fahim Parkar

1

Я отправил свой ответ на другой пост с тем же вопросом, что и этот.

Из Руководства по переходу на Apple iOS7, https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/TransitionGuide/AppearanceCustomization.html#//apple_ref/doc/uid/TP40013174-CH15-SW1

В частности, automaticallyAdjustsScrollViewInsets=YESи set self.edgesForExtendedLayout = UIRectEdgeNoneработает для меня, когда я не хочу дублирования и у меня есть файл tableviewcontroller.


0

Если вы хотите, чтобы любой ценой был включен параметр «Использовать автоматическое размещение», поместите следующий код в viewdidload.

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) 
{
        self.edgesForExtendedLayout = UIRectEdgeNone;
        self.extendedLayoutIncludesOpaqueBars = NO;
        self.automaticallyAdjustsScrollViewInsets = NO;
}

0

Моя строка состояния и панель навигации перекрываются после возврата из альбомного режима YTPlayer. Вот мое решение после попытки версии @comonitos, но не работающей на моей iOS 8

- (void)fixNavigationBarPosition {
    if (self.navigationController) {
        CGRect frame = self.navigationController.navigationBar.frame;
        if (frame.origin.y != 20.f) {
            frame.origin.y = 20.f;
            self.navigationController.navigationBar.frame = frame;
        }
    }
}

Просто вызывайте эту функцию всякий раз, когда вы хотите исправить положение панели навигации. Я позвонил в YTPlayerViewDelegateplayerView:didChangeToState:

- (void)playerView:(YTPlayerView *)playerView didChangeToState:(YTPlayerState)state {
    switch (state) {
        case kYTPlayerStatePaused:
        case kYTPlayerStateEnded:
            [self fixNavigationBarPosition];
            break;
        default:
    }
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.