Рядок стану iOS 7 назад до стилю за замовчуванням iOS 6 в додатку iPhone?


292

У iOS 7 UIStatusBarрозроблений таким чином, що він зливається з таким виглядом:

GUI, розроблений Тіною Тавчар (GUI розроблений Тіною Тавчар )

  • Це круто, але це дещо зіпсує ваш погляд, коли у вас є щось у верхній частині перегляду, і воно перекриється рядком стану.

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

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

  • Я дійсно буду радий, якщо хтось може надати мені однолінійне рішення для цього.

PS Я знаю, що можу приховати рядок стану, виконуючи такі дії, як, наприклад, наявність

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

У didFinishLaunchingWithOptionsметоді, але це вирішення, ярлик, який дозволяє уникнути проблеми, тому я не вважаю це справжнім рішенням.


6
У ios 7
i_duhh_bomb

Я погоджуся з @GangstaGraham. Ці кольори просто красиві ! Щоб відповісти на ваше запитання, боюся, ви не можете. Причина, за якою зараз створено рядок стану, полягає в тому, що напівпрозорість - це нова річ iOS, і вона створена для надання «глибини» додатку, кажучи, що він знаходиться над чим-небудь, тому під цим є щось.
Коул Джонсон

Ви спробували встановити перевагуStatusBarStyle для UIStatusBarDefault? Оформити замовлення IOS 7 UIViewController Документація
theaob

1
Наявність UIStatusBarDefaultдля рядка стану лише робить її вміст чорним кольором. Він не збирається робити так, як він функціонує назад, як він знаходиться в iOS6.
吖 奇 说 - 何魏奇 Archy Will He

2
Пощастило з цим? Я люблю iOS7, але ця річ зводить мене з розуму!
Mihai Fratu

Відповіді:


449

Це перекладене повідомлення з написаного мною блогу , але ось повний перехід на панелі стану, панелі навігації та контролери перегляду контейнерів на iOS 7:

  1. Неможливо зберегти макет рядка стану iOS 6. Рядок стану завжди буде перекривати вашу програму на iOS 7

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

  3. Зовнішній вигляд рядка стану контролюється по одному з двох взаємовиключних базових контурів: ви можете встановити їх програмно традиційним чином, або UIKit оновить зовнішній вигляд для вас на основі деяких нових властивостей UIViewController. Остання опція за замовчуванням увімкнена. Перевірте значення плістів програми на предмет "Зовнішній вигляд панелі стану на основі ViewController", щоб побачити, який ви використовуєте. Якщо ви встановите це значення "ТАК", кожен контролер подання верхнього рівня у вашій програмі (крім стандартного контролера перегляду контейнерів UIKit) повинен перекрити preferenceStatusBarStyle, повернувши або стиль за замовчуванням, або світло. Якщо ви відредагуєте значення plist на NO, ви можете керувати зовнішнім виглядом рядка стану, використовуючи звичні методи UIApplication.

  4. UINavigationController змінить висоту свого UINavigationBar до 44 балів або 64 балів, залежно від досить дивного та недокументованого набору обмежень. Якщо UINavigationController виявить, що верхня частина кадру його зору візуально поєднується з верхньою частиною його вікна UIWindow, то вона намалює панель навігації висотою 64 точок. Якщо вершина його виду не є суміжною з вершиною UIWindow (навіть якщо вимкненою лише однією точкою), вона намалює панель навігації «традиційним» способом висотою 44 бали. Цю логіку виконує UINavigationController, навіть якщо в ієрархії контролера подання даних у вашій програмі є кілька дітей. Не можна запобігти такій поведінці.

  5. Якщо ви надаєте фонове зображення для користувальницької навігаційної панелі, яке становить лише 44 пункти (88 пікселів), і межі перегляду UINavigationController відповідають межам вікна UIW (як обговорюється в # 4), UINavigationController намалюватиме ваше зображення у кадрі (0,20320 , 44), залишаючи 20 точок непрозорого чорного простору над вашим власним зображенням. Це може заплутати вас у думці, що ви розумний розробник, який обійшов правило №1, але ви помиляєтесь. Панель навігації все ще становить 64 бали. Вбудовування UINavigationController в ієрархію стилю перегляду слайдів для виявлення робить це досить зрозумілим.

  6. Остерігайтеся властивості UIViewController заплутано названих краївForExtendedLayout. Регулювання краївForExtendedLayout в більшості випадків нічого не робить. Єдиний спосіб, коли UIKit використовує цю властивість, це якщо ви додаєте контролер перегляду до UINavigationController, тоді UINavigationController використовує edgeForExtendedLayout, щоб визначити, чи повинен його контролер подання дочірніх даних відображатися під панеллю навігації / панелі стану. Встановлення edgeForExtendedLayout на UINavigationController сам по собі нічого не змінює, чи має UINavigationController 44 або 64-бальну зону навігаційної панелі. Дивіться №4 щодо цієї логіки. Подібна логіка компонування застосовується внизу вашого перегляду при використанні панелі інструментів або UITabBarController.

  7. Якщо все, що ви намагаєтеся зробити, це не допустити, щоб ваш користувальницький контролер дитячого перегляду не перекривав панель навігації під час UINavigationController, то встановіть edgeForExtendedLayout на UIRectEdgeNone (або принаймні маску, що виключає UIRectEdgeTop). Встановіть це значення якомога раніше в життєвому циклі контролера перегляду.

  8. UINavigationController та UITabBarController також намагатимуться вкласти в контент представлення таблиць та представлення колекцій у своїй ієрархії підпідгляду. Це робиться таким чином, як аналогічний логіці рядка стану від №4. Існує програмний спосіб запобігти цьому, встановивши автоматичноAdjustsScrollViewInsets на "НІ" для представлень ваших таблиць і переглядів колекції (це за замовчуванням YES). Це створювало серйозні проблеми для Whisper і Riposte, оскільки ми використовуємо налаштування contentInset для управління компонуванням подань таблиць у відповідь на рух панелі інструментів та клавіатури.

  9. Ще раз повторюю: немає можливості повернутися до логіки компонування рядка стану в стилі iOS 6. Для того, щоб наблизити це, вам потрібно перемістити всі контролери подання програми у вікні контейнера, який зміщений на 20 точок у верхній частині екрана, залишаючи навмисне чорний вигляд за рядком стану, щоб імітувати старий вигляд. Це метод, який ми в кінцевому підсумку застосували в Riposte та Whisper.

  10. Apple дуже наполегливо наполягає на тому, щоб не намагатися зробити номер 9. Вони хочуть, щоб ми переробили всі наші додатки, щоб перекрити рядок стану. Однак є багато спірних аргументів як з досвіду користувача, так і з технічних причин, чому це не завжди є хорошою ідеєю. Ви повинні робити те, що найкраще для своїх користувачів, а не просто слідувати примхи платформи.


35
Просто хотілося б додати, що ви можете додати обмеження до того, що знаходиться у верхній частині вашого подання, щоб бути приєднаним до верхнього керівництва щодо макета - це залишить порожнє місце за рядком стану (яке ви можете заповнити будь-яким кольором). але також дозволить перегляду автоматично підлаштовуватися під правильне положення в iOS 6. Таким чином, вам не доведеться вручну коригувати положення своїх поглядів у коді.
BreadicalMD

4
Це геніальне рішення. Ви викрили моє незнання на AutoLayout. Краще займіться цим.
jaredsinclair

1
Якщо ви розмістите верхній простір об’єкта під краєм верхнього напрямника макета, ви можете скористатися керуванням обмеженням, щоб додати до найближчого сусіда вертикальне обмеження між інтервалом, яке тепер буде верхнім настановою для компонування. Крім того, ви можете використовувати ctrl + клацання від вашого об'єкта до верхнього керівництва макета, щоб явно додати обмеження вертикального інтервалу.
BreadicalMD

2
@BreadicalMD Одну частину, яку я не розумію, є те, що -topLayoutGuide не доступний на iOS 6, тож це означає, що вам потрібно використовувати різні обмеження автоматичного макета на iOS 7 та 6?
Джеремі

1
Чудова відповідь ... Але в мене є сумніви 1) UINavigationController, що змінює частину висоти. Поясніть це ще трохи. спасибі
користувач1010819

122

Оновлення 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, і це найкоротший шлях, який я можу придумати:

  1. Набір UIViewControllerBasedStatusBarAppearanceдля NOв info.plist(Щоб відмовитися від того, переглядати контролери налаштувати стиль рядка стану , так що ми можемо поставити стиль рядка стану за допомогою методу UIApplicationstatusBarStyle.)

  2. У програмі 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;
    


щоб:

  1. Перевірте, чи це iOS 7.

  2. Встановіть вміст рядка стану білим, на відміну від UIStatusBarStyleDefault.

  3. Уникайте, щоб субпогляди, рамки яких виходять за межі видимих ​​меж, не з’являлися (для представлень, що перетворюються на головний вигляд зверху).

  4. Створіть ілюзію, що рядок стану займає простір, як, наприклад, в 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);
    }
}

Так що, коли орієнтація змінюється, вона запустить оператор перемикання, щоб виявити орієнтацію екрана програми (Портрет, Вгору вниз, Пейзаж ліворуч або Пейзаж праворуч) та змінить відповідно віконну рамку програми, щоб створити ілюзію рядка стану iOS 6.


Щоб змінити колір тла рядка стану:

Додайте

 @property (retain, nonatomic) UIWindow *background;

в , AppDelegate.hщоб зробити backgroundвластивість в класі і запобігти ARC від deallocating його. (Вам не доведеться робити це, якщо ви не використовуєте ARC.)

Після цього вам просто потрібно створити вікно UIW у 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
Це порушується при обертанні. просто голова вгору
Джессі Наугер

2
@JesseNaugher Я рекомендую програмно змінити обмеження на вертикальний інтервал від 0 до 20. Він буде працювати на обертання.
експерт

2
Будь-яка ідея про те, як ми можемо уникнути розширення панелі навігації на 20 пікселів? Для мене це рішення добре, але мій панель навігації зависокий на 20 пікселів.
simonbs

4
@ArchyHolt: Ваше просте рішення працює для мене, за винятком випадків, коли я представляю контролер модального перегляду. Після того, як контролер модального перегляду буде відмовлено, решта подання перебуває під рядком стану. Я відтворив це в новому зразковому проекті, щоб переконатися, що більше нічого фанкічного не відбувається. Я думаю, можливо, ваше більш просунуте рішення може бути корисним тут, але не впевнений, яке сповіщення увійде в дію. Будь-які ідеї?
markdorison

4
Перегляд відновлюється після відхилення контролера модального перегляду. :(
KarenAnne

41

ОНОВЛЕННЯ (НОВЕ РІШЕННЯ)

Це оновлення - найкраще рішення проблеми навігаційної панелі 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;

}

СТАРИЙ РІШЕННЯ - Якщо ви використовуєте попередній код, проігноруйте наступний код та зображення

Це стара версія рішення навігаційної панелі 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 з'являються лише у тому випадку, якщо ви зніміть прапорець "Використовувати автоматичний розклад" для контролера перегляду в "Інспекторі файлів" (сама ліва піктограма) на панелі деталей.

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


6
Ти зробив мій день. Взяти +1 за допомогу!
Ніру Мукунд Шах

5
Зверніть увагу: дельтати iOS 6/7 з'являються лише у тому випадку, якщо ви зніміть прапорець "Використовувати автоматичну розстановку" для контролера перегляду в "Інспекторі файлів" (самої лівої піктограми) на панелі деталей.
Метт

1
Дуже дякую! Ти врятував мені багато клопоту!
neowinston

2
Хто сказав, що макет рядка стану iOS 6 не може бути збережений. Ви можете це зробити за допомогою @ TacettinÖzbölük способу ... дякую товаришу за це рішення Awsum.
Vizllx

1
хороший! також, просто зауважте, яблуко воліє це зараз: якщо (NSFoundationVersionNumber> = NSFoundationVersionNumber_iOS_6_1) {}
Джоель Балмер

26

РІШЕННЯ:

Встановіть його у своєму контролері перегляду або в rootviewcontroller, замінивши метод:

-(BOOL) prefersStatusBarHidden
    {
        return YES;
    }

Непогане рішення. Повністю зніміть планку. Це може бути ідеально для UX весь час, але працездатним.
Farhan Hafeez

Просто Awesome. Працював для мене бездоганно.
madLokesh

Сценарій: Після переключення назад на свій UIVIew після відтворення відео на повноекранному екрані внизу з’являється чорна смуга, яка є лише розміром рядка стану, хоча я вже використовував рядок стану. Я повністю видалив рядок стану, і тепер проблема виправлена.
madLokesh

Я успішно користуюся цим методом
user2277872

17

Ось ще один підхід для проектів, які широко використовують Розгорнуту дошку:

МЕТА:

Мета цього підходу - відтворити той самий стиль рядка стану в iOS7, який був у iOS6 (див. Заголовок питання "Положення стану iOS 7 Повернутися до стилю iOS 6?").

РЕЗЮМЕ:

Щоб досягти цього, ми максимально використовуємо дошку розгортання, переміщуючи елементи інтерфейсу, які перекриваються рядком стану (під iOS 7) вниз, використовуючи дельти, щоб повернути зміни макета вниз для iOS 6.1 або раніше. Отриманий додатковий простір в iOS 7 потім займає UIView з кольором backgroundColor, встановленим під обраний нами колір. Останні можуть бути створені в коді або за допомогою Інструкції (див. АЛЬТЕРНАТИВИ нижче)

ПРИМІТКИ:

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

КРОКИ:

  • Додайте підперегляд у вікно UIW, щоб послужити фоном рядка стану. Щоб досягти цього, додайте наступне в 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" не відображається в Інспекторі розмірів). Зробити це:
      • виберіть файл розгортки
      • показати Утиліти
      • виберіть "Показати інспектор файлів"
      • У розділі "Документ для створення інтерфейсу" зніміть прапорець "Використовувати автоматичний розклад"
    • Необов’язково, щоб допомогти вам відстежувати зміни макета для iOS 7 І 6 під час їх застосування, виберіть "Помічник редактора", виберіть "Попередній перегляд" та "iOS 6.1 або новіші": введіть тут опис зображення введіть тут опис зображення
    • Тепер виберіть елемент інтерфейсу, який потрібно налаштувати, щоб він більше не перекривався рядком стану
    • У стовпці "Утиліти" виберіть "Показати інспектор розміру"
    • Розмістіть свій елемент інтерфейсу вздовж осі Y на ту саму суму, що і висота bg смуги стану: введіть тут опис зображення
    • І змініть значення iOS6 / 7 Deltas на Y на ту саму НЕГАТИВНУ суму, що і висоту панелі стану (Зверніть увагу на зміну попереднього перегляду iOS 6, якщо ви його використовуєте): введіть тут опис зображення

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

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

Недоліком цієї альтернативи (хоча, можливо, мізерним з огляду на сумісність авторотату) є той факт, що цей додатковий вигляд не відразу видно, якщо ви переглядаєте сторінку Storyboard для iOS 6. Ви б знали лише, що вона існує, якби ви подивилися на " Структура документа "на Розговорці.


12

Якщо ви не хочете, щоб ваші контролери перегляду перекривались смужкою стану (та навігаційними панелями), зніміть прапорець "Розширити краї під верхніми смугами" у програмі Interface Builder у Xcode 5.

Зніміть прапорці Розширені краї під верхніми брусками


7
Це можливо лише в тому випадку, якщо ви використовуєте дошку розкадрувань
Cœur

3
Він працює лише з контейнерами, зокрема контролерами навігації або контролером вкладки
Андреа,

2
edgeForExtendedLayout використовується лише контролерами перегляду контейнерів (наприклад, UINavigationController), щоб визначити, чи повинні перегляди його дітей перекриватися хромом батьків. Якщо встановити це властивість у контролері кореневого виду для вікна UIW, це нічого не робить. Дивіться мою відповідь вище: stackoverflow.com/questions/18294872 / ...
jaredsinclair

Як це зробити для UITabBarController @Andrea? Дякую.
KarenAnne

@KarenAnne Залежить, якщо ти займаєшся програмно або з розповідями. Програмно вам потрібно просто встановити властивість edgeForExtent на те, що вам подобається в контролері перегляду, який ви показуєте всередині UITabBarViewController, але щоб у вас не виникло проблеми в рядку стану, ви повинні завантажити контролер uinavigation всередину UITabbarController. Перевірте тут. developer.apple.com/library/ios/documentation/UserExperience/…
Андреа,

11

Apple випустила технічні запитання QA1797: запобігання висвітленню ваших поглядів у рядку стану . Він відмінно працює для версій iOS 6 та iOS 7.


5
Apple припускає, що всі використовують автоматичне розташування. Автоматичний макет був жахливим у Xcode 4, а Xcode 5 тільки що вийшов, тому це сумнівне припущення.
Гленн Мейнард

1
Але в перспективі це краще рішення, а потім змінити розмір кадру кореневого вікна або рядка стану.
Ігор

Наскільки я можу сказати, рішення Apple не працює, якщо ваш rootViewController є splitViewController.
Vern Jensen

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

Логіка проста. Я перекладаю всі дитячі погляди на самоперегляд з 20 пікселів. Це все. Потім знімок екрана відображатиметься так само, як і iOS 6. Я ненавиджу рядок стану iOS7! ~ "~


2
куди мені це додати? у делегата програми запускався з опціями?
mhmdshawqi

Коли я це роблю, мій рядок стану стає білим
ropo

6

Невелика альтернатива відповіді Арчі Холта, трохи простіша:

а. Набір UIViewControllerBasedStatusBarAppearanceдля NOв 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самої обробки .


у вас проблеми з presentViewController: animiran: завершення:?
Tùng Đỗ

@ TùngĐỗ правда, тому я зробив альтернативу, яка працює краще: stackoverflow.com/questions/18294872/…
Cœur

5

Я використовував це у всіх контролерах мого перегляду, це просто. Додайте ці рядки до всіх своїх методів viewDidLoad:

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

    [super viewDidLoad];
}

1
Працював як шарм, а мертвим легко. У рубіновому русі, перед закликом до супер використання: self.edgesForExtendedLayout = UIRectEdgeNone, якщо відповідаєToSelector ("edgeForExtendedLayout")
tehprofessor

4

Спробуйте цей простий метод ....

Крок 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];
    }

3

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

Погляньте на це в "Стійке переповнення запитання" Інтерфейс для побудови інтерфейсу: для чого призначений дельтати розміщення UIView iOS 6/7? .


3

Я досягнув рядка статусу, як iOS 6 в iOS 7.

Встановіть UIViewControllerBasedStatusBarApperance на 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"];

Кращий підхід - зробити так, щоб ваш UINavigationBar heightдорівнював 64, а не 44. Тоді ваш бар буде простягатися до верху, як в додатках Apple.
Аарон Брагер

@AaronBrager Але моя вимога полягала в тому, щоб показати рядок стану стилю iOS 6.
Пустельна троянда

Ви можете додати рішення для iOS 7 Landscape Orientation? Я роблю те саме. але це не працює в iOS 7 Landscape.
sathiamoorthy

@DesertRose THX! Це працює для мене, але він відрізає uitabbar внизу. У мене є додаток на основі контролера панелі вкладок з 3 переглядами, 2 з яких - контролери настільних оглядів.
marciokoko

1
Доки я не обертаю пристрій (мій пристрій iOS 7 - це iPad), це ідеально виправляє його. Але як тільки я обертаюсь, чорна смуга залишається саме там, де вона є, і "вигляд" (вибачте, якщо це неправильний технічний термін, я - PhoneGap / веб-хлопець) підтримує свою зменшену висоту - за винятком того, що це вже не висота, це ширина. Це рішення не підтримує обертання, але це найкраще виправлення, яке я бачив - як його можна вдосконалити, щоб спостерігати за обертаннями пристроїв? Дякую!
tylerl

2

Якщо ви використовуєте конструктор інтерфейсів, спробуйте це:

У вашому файлі xib:

1) Виберіть основний вид, встановіть колір тла чорний (або будь-який колір, у якому ви хочете, щоб рядок стану був)

2) Переконайтесь, що фон - це автономний підвід, розміщений як дочірній вигляд верхнього рівня з точки зору контролера.
Перемістіть своє тло, щоб стати прямою дочкою зору контролера. Перевірте панель автоматизації, щоб переконатися, що ви заблокували всі краї кадру, активували обидві осі гнучкості, і якщо це UIImageView, встановіть для змістового режиму масштаб для заповнення. Програмно це перекладається на contentMode, встановлений на UIViewContentModeScaleToFill, і його маску автоматичного розміру встановлено на (UIViewAutoresizingFfleWidth | UIViewAutoresizingFfleHeight).

3) Тепер перемістіть усе, що заблоковано вгору - вниз на 20 балів, і встановіть iOS 6/7 дельту Y на -20.
Усі діти верхнього рівня, які заблоковані до верхнього кадру на панелі автоматизації, повинні бути переміщені на 20 крапель і встановити їх дельту Y для iOS 6/7 на -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


Немає дельт при використанні автоматичного макета
загублений переклад

2

Моє рішення було додати 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]коли це потрібно.


2

Це може бути надзвичайною проблемою, якщо ви використовуєте автоматичний макет, оскільки ви більше не можете безпосередньо маніпулювати кадрами. Існує просте рішення без зайвої роботи.

Я закінчив писати утилітний метод в класі утиліти і викликав його з усіх viewDidLayoutSubviewsметодів контролерів перегляду .

+ (void)addStatusBarIfiOS7:(UIViewController *)vc
    {
        if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) {
            CGRect viewFrame = vc.view.frame;
            if(viewFrame.origin.y == 20) {
                //If the view's 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];
}

1

Найпростіший спосіб зробити це - встановити старіший SDK до найновішого Xcode.

Як встановити старіший SDK до найновішого Xcode?

  1. Ви можете отримати iOS 6.1 SDK від http://www.4shared.com/zip/NlPgsxz6/iPhoneOS61sdk.html або завантажити старіший Xcode та отримати SDK з його вмісту

  2. Розпакуйте та вставте цю папку в /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs

  3. Перезавантажте xcode.

  4. Тепер ви можете вибрати старіший SDK у налаштуваннях проекту

Сподіваюся, це допоможе вам. Це працювало для мене =)


працював на мене. дякую @marcelosalloum, але все ще шукаю вирішення для мого додатка phonegap (uiwebview), щоб підтримати прозорий рядок стану iOS7 для подальшого оновлення мого додатка. знову дякую. ;)
ханізм

@marcellosaloum, ви впевнені, що додаток буде прийнято Apple? Вони сказали, що програми, компільовані з XCode 4, більше не приймаються ... це фактично означає iOS 6 SDK.
Валеріо

Моя програма дійсно прийнята, оскільки Xcode5 може компілювати старі SDK для iOS. Я не впевнений, чи AppStore відхилить вбудовані програми Xcode4, але (Xcode4! = IOS 6 SDK), як ви вже говорили.
marcelosalloum

Це було після 1 лютого? У той день Apple зробила це обов’язковим.
Валеріо

Ні, останній раз торкнувся цього коду минулого року, народному. Я не знав, що Apple зробила це обов'язковим (хоча не радий знати). Чи можете ви опублікувати тут посилання, яке говорить про це? Ура
марцелосаллум

1

У міру використання 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.


1

Я запізнююсь на цю відповідь, але я просто хочу поділитися тим, що я зробив, що в основному є найпростішим рішенням

Перш за все-> Перейдіть до свого 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;
   }

0

Моє дуже просте рішення (якщо припустити, що у вас підтримується лише вертикальна орієнтація) - переосмислити межі вікна додатків для версій 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];
}

Ваш код просто зміщує 'y' з 0 на 20, але не регулює відповідно висоту, тому слід додати screenBounds.size.height - = 20; відразу після screenBounds.origin.y = 20;
Аміт C.

0

Ви можете приховати рядок стану всі разом. Тож ваш додаток буде повноекранним. Я думаю, що це найкраще, що ти отримаєш.

UIStatusBarStyleNone або встановити в цільових налаштуваннях.


2
де вказати UIStatusbarstylenone
user4951

0

Крок для приховування рядка стану в iOS 7:

1.Перейти до файлу info.plist програми.

2.І встановіть, перегляньте зовнішній вигляд рядка стану на основі контролера: булевий НІ

Сподіваюсь, я вирішив питання рядка стану .....


0

Щоб продовжувати роботу з 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


0

Це може бути занадто пізно, щоб поділитися, але я маю щось внести, що могло б допомогти комусь, я намагався підкласити 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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.