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.