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


109

У мене є a, ViewControllerякий знаходиться всередині UINavigationcontroller, але навігація Bar прихована. Коли я запускаю додаток на iOS 7, на моєму огляді відображається рядок стану. Чи є спосіб цього уникнути?

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

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

Я спробував встановити View controller-based status bar appearanceв NO, але не вирішити проблему.


Я опублікував свою відповідь, щоб показати рядок стану, як iOS 6 в iOS 7, stackoverflow.com/questions/18294872/…
— Desert Rose

2
Вам потрібно відрегулювати значення походження та дельти, а також вирішити проблему з рядком стану. Це може допомогти вам 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-
— дюймових iphone

5
працював на мене. Зауважте, що для того, щоб побачити цю дельту, вам потрібно зняти позначку "Використовувати автовідклад" у розділі "Ідентифікація та тип" для аркуша розкадри.
— мерсант

2
Я з'ясував, що, крім встановлення -20 для ∆Y, мені довелося також встановити +20 на ∆Height
— Toland Hon

3
Що станеться, коли висота панелі стану зміниться? F.ex .: коли користувач активує гарячу точку тощо, то висота 40px ...
— Лукаш

69

Якщо ви просто НЕ бажаєте будь-якої панелі стану, вам потрібно оновити ваш список із цими даними: Для цього в плейст додайте ці 2 налаштування:

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

В iOS 7 очікується, що ви спроектуєте додаток із накладеною прозорою смужкою стану. Наприклад, подивіться нову програму iOS 7 Weather.


3
Це насправді єдина хороша відповідь, оскільки вона вирішує проблему в своїй суті так, як це мало бути зроблено. Отже: потрібні оновлення!
— одинадцять59

5
Це може бути доречно в деяких ситуаціях, але ви хочете бути дуже обережними, ховаючи рядок стану. Тільки для переглядів, які мають виправдання на весь екран, як-от медіа-плеєри чи переглядачі зображень.
— smileBot

1
@ eleven59, ви маєте на увазі так, як планують автократи Apple.
— JohnK

1
Однозначно подобається це краще, ніж змінювати зміщення контролера перегляду (який відчуває себе справді брудно).
— Бенджамін Оман

приховувати рядок стану - це не дуже гарна ідея ... Я знаю, що це найпростіший спосіб впоратися з iOS 7, але потрібні терміни ...
— Фахім Паркяр

43

Це поведінка за замовчуванням для UIViewControlleriOS 7. Перегляд буде повноекранним, це означає, що рядок стану буде охоплювати верхню частину вашого перегляду.

Якщо у вас є в UIViewControllerмежах UINavigationControllerі Панель навігації видно, ви можете мати наступний код в вашому viewDidLoadабо мати фонове зображення для Панель навігації зробити трюк.

self.edgesForExtendedLayout = UIRectEdgeNone;

Якщо у вас навігація Barbar прихована, вам доведеться відрегулювати всі елементи 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 слід використати preferenceStatusBarStyle у контролері перегляду, оскільки 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);
    }
  }
}

Додати ключ у списку --- Перегляд зовнішнього вигляду рядка стану на основі контролера: НІ


змінити колір вікна, якщо потрібно
— Darshit Shah

Дякую, це вирішило мою проблему, що перетинається. Але одне питання все ще існує - Перегляд зовнішнього вигляду рядка стану на основі контролера: НІ, мабуть, приховувати рядок стану. Але коли я встановив його "ТАК", то його рядок стану не відображається, а коли я встановив "НІ", він відображає рядок стану. Отже, скажіть мені, помиляюся з концепцією чи що?
— Наян

1
Я думаю, тому що прийміть напівпрозорий колір напівпрозорого кольору у didFinishLaunchingWithOptions 'self.window.backgroundColor = [UIColor blueColor];' і встановіть у рядку статусу на основі контролера View YES
— Darshit Shah

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

Дякую тобі. Ваш код настільки корисний для нас. Потрібно пояснити про функцію viewWillLayoutSubviews.
— користувач3182143

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вгорі " " і натисніть + значок


Прочитайте питання чітко, Він не просив повністю приховати рядок стану.
— ШаянК

1
@AspersionCast: Він запитав "Чи є спосіб уникнути цього?" і це один із способів уникнути цього.
— Mandeep Pasbola


3

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

xib heirarchy

а потім 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;
  }
}

Таким чином, nibs не потрібно змінювати для сумісності iOS 7. Якщо у вас є фон, його можна зберігати зовні containerViewі нехай він охоплює весь екран.



2

Для панелі навігації:

Написання цього коду:

self.navigationController.navigationBar.translucent = NO;

просто зробив для мене трюк.


1

На мене працював край відповіді ВінсентаForExtendedLayout.

Ці макроси допомагають визначити версію ОС, полегшивши її

// 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; не працює ... з якоїсь причини?
— Фахім Паркар

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

Якщо ви хочете, щоб "Використовувати автоматичний розклад" будь-якою ціною було ввімкнено наступний код для перегляду.

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.