строка состояния ios 7 возвращается к стилю ios 6 по умолчанию в приложении iphone?

<p>в ios 7 <code>uistatusbar</code> был разработан таким образом, что он сливается с представлением, подобным этому:</p><p><img src="https://i.stack.imgur.com/rfo0q.png" alt="gui designed by tina tavčar"> (gui разработан <a href="http://dribbble.com/shots/1183911-side-menu-and-status-bar-in-ios7">тина тавчар</a> )</p><ul> <li><p>это круто, но это несколько испортит ваш взгляд, когда у вас есть что-то в верхней части вашего обзора, и это будет перекрываться со строкой состояния.</p></li> <li><p>есть ли простое решение (например, установка свойства в info.plist), которое может изменить способ его работы [не перекрывая] обратно на то, как оно работает в ios6? </p></li> <li><p>я знаю, что более простое решение - иметь <code>self.view.center.x</code> + 20 баллов для каждого отдельного контроллера представления, но изменение их приведет к искажению других измерений (наличие другого <code>self.view.center.x</code> может вызвать проблемы для пользовательских сегментов и т.д.), и внезапно оно превращается в утомительную работу. этого лучше всего избегать. </p></li> <li><p>я действительно буду рад, если кто-то может предоставить мне однострочное решение для этого.</p></li> </ul><p>постскриптум я знаю, что могу скрыть строку состояния, делая такие вещи, как</p><pre><code>[[uiapplication sharedapplication] setstatusbarhidden:yes withanimation:uistatusbaranimationnone]; </code></pre><p>в методе <code>didfinishlaunchingwithoptions</code>, но это обходной путь, ярлык позволяет избежать проблемы, поэтому я не считаю это реальным решением.</p>

<p>это перекрестная публикация из <a href="http://blog.jaredsinclair.com/post/61507315630/wrestling-with-status-bars-and-navigation-bars-on-ios-7">сообщения в блоге, которое я написал</a> , но вот полное изложение строк состояния, панелей навигации и контроллеров представления контейнера в ios 7:</p><ol> <li><p>нет способа сохранить макет строки состояния стиля ios 6. строка состояния всегда будет перекрывать ваше приложение на ios 7</p></li> <li><p>не путайте внешний вид строки состояния с разметкой строки состояния. внешний вид (светлый или по умолчанию) не влияет на расположение строки состояния (рамка/высота/перекрытие). также важно отметить, что строка состояния системы больше не имеет цвета фона. когда api ссылается на uistatusbarstylelightcontent, они означают белый текст на чистом фоне. uistatusbarstyledefault - черный текст на чистом фоне.</p></li> <li><p>внешний вид строки состояния контролируется по одному из двух взаимоисключающих базовых путей: вы можете либо установить их программным способом традиционным способом, либо uikit обновит внешний вид для вас на основе некоторых новых свойств uiviewcontroller. последний вариант включен по умолчанию. проверьте значение plist вашего приложения для «внешний вид строки состояния на основе viewcontroller», чтобы увидеть, какой из них вы используете. если вы установите для этого значения значение yes, каждый контроллер представления верхнего уровня в вашем приложении (кроме стандартного контроллера представления контейнера uikit) должен переопределить предпочитаемыйstatusbarstyle, возвращая либо стиль по умолчанию, либо стиль освещения. если вы измените значение plist на no, то вы можете управлять внешним видом строки состояния, используя знакомые методы uiapplication.</p></li> <li><p>uinavigationcontroller изменит высоту своего uinavigationbar до 44 или 64 точек, в зависимости от довольно странного и недокументированного набора ограничений. если uinavigationcontroller обнаруживает, что верхняя часть рамки его вида визуально соприкасается с верхней частью своего uiwindow, тогда он рисует свою панель навигации с высотой 64 точки. если его вершина не соприкасается с вершиной окна uiwindow (даже если она отклонена только на одну точку), тогда она рисует свою навигационную панель «традиционным» способом с высотой 44 точки. <strong>эта логика выполняется uinavigationcontroller, даже если в иерархии контроллера представления вашего приложения есть несколько дочерних элементов.</strong> нет способа предотвратить такое поведение.</p></li> <li><p>если вы предоставляете пользовательское фоновое изображение панели навигации высотой всего 44 точки (88 пикселей) и границы представления uinavigationcontroller совпадают с границами uiwindow (как обсуждалось в # 4), uinavigationcontroller будет рисовать ваше изображение в кадре (0,20,320 , 44), оставляя 20 точек непрозрачного черного пространства над вашим изображением. это может сбить вас с толку, если вы будете думать, что вы умный разработчик, который обошел правило № 1, но вы ошибаетесь. панель навигации по-прежнему 64 балла. внедрение uinavigationcontroller в иерархию представлений стиля со слайдом для раскрытия делает это совершенно ясным.</p></li> <li><p>остерегайтесь запутанно названного свойстваdgeforextendedlayout uiviewcontroller. регулировка edgeforextendedlayout в большинстве случаев ничего не делает. единственный способ, которым uikit использует это свойство, - это если вы добавляете контроллер представления в uinavigationcontroller, тогда uinavigationcontroller используетdgeforextendedlayout, чтобы определить, должен ли его дочерний контроллер представления быть видимым под областью панели навигации/строки состояния. установка edgeforextendedlayout в самом uinavigationcontroller не влияет на то, имеет ли uinavigationcontroller область навигации с 44 или 64 точками. смотрите # 4 для этой логики. подобная логика расположения применима к нижней части вашего представления при использовании панели инструментов или uitabbarcontroller.</p></li> <li><p>если все, что вы пытаетесь сделать, - это не допустить, чтобы ваш пользовательский дочерний контроллер представления перекрывал панель навигации, когда он находится внутри uinavigationcontroller, то установите дляdgeforextendedlayout значение uirectedgenone (или, по крайней мере, маску, исключающую uirectedgetop). установите это значение как можно раньше в жизненном цикле вашего контроллера представления.</p></li> <li><p>uinavigationcontroller и uitabbarcontroller также попытаются дополнить contentinsets табличных представлений и коллекционных представлений своей иерархией подпредставлений. это происходит аналогично логике строки состояния из # 4. существует программный способ предотвратить это, автоматически устанавливая adjustsscrollviewinsets в no для ваших табличных представлений и представлений коллекции (по умолчанию yes). это создало серьезные проблемы для whisper и riposte, поскольку мы используем настройки contentinset для управления макетом табличных представлений в ответ на движения панели инструментов и клавиатуры.</p></li> <li><p>повторим: нет способа вернуться к логике макета строки состояния в стиле ios 6. чтобы приблизиться к этому, вы должны переместить все контроллеры представления вашего приложения в представление контейнера, которое смещено на 20 точек от верхней части экрана, оставляя намеренно черный вид за строкой состояния для имитации старого вида. этот метод мы использовали в riposte и whisper.apple очень старается, чтобы вы не пытались сделать № 9. они хотят, чтобы мы перепроектировали все наши приложения так, чтобы они перекрывали строку состояния. однако существует множество убедительных аргументов как по пользовательскому опыту, так и по техническим причинам, почему это не всегда хорошая идея. вы должны делать то, что лучше для ваших пользователей, а не просто следовать прихоти платформы.</p></li> <li><p>apple is pushing very hard to ensure that you don’t try to do #9. they want us to redesign all our apps to underlap the status bar. there are many cogent arguments, however, for both user experience and technical reasons, why this is not always a good idea. you should do what is best for your users and not simply follow the whimsy of the platform.</p></li> </ol>

<blockquote> <p>обновления от 19 сентября 2013 года:</p> <p><sub> исправлены ошибки масштабирования путем добавления <code>self.window.bounds = cgrectmake(0, 20, self.window.frame.size.width, self.window.frame.size.height);</code> </sub></p> <p><sub> исправлены опечатки в выражении <code>nsnotificationcenter</code> </sub></p> </blockquote><p><br></p><blockquote> <p>обновления от 12 сентября 2013 года:</p> <p><sub>исправлено <code>uiviewcontrollerbasedstatusbarappearance</code> в <code>no</code></sub></p> <p><sub>добавлено решение для приложений с поворотом экрана</sub></p> <p><sub>добавлен подход для изменения цвета фона строки состояния.</sub></p> </blockquote><p><br></p><p>по-видимому, нет способа вернуть строку состояния ios7 обратно к тому, как она работает в ios6. </p><p>тем не менее, мы всегда можем написать некоторые коды и превратить строку состояния в ios6-подобный, и это самый короткий способ, который я могу придумать:</p><ol> <li><p>установите для <code>uiviewcontrollerbasedstatusbarappearance</code> значение <code>no</code> в <code>info.plist</code> (чтобы отказаться от наличия контроллеров представления, отрегулируйте стиль строки состояния, чтобы мы могли установить стиль строки состояния с помощью метода uiapplicationstatusbarstyle.)</p></li> <li><p>в <code>application:didfinishlaunchingwithoptions</code> appdelegate, позвоните</p> <pre><code>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; </code></pre></li> </ol><p><br></p><p>чтобы:</p><ol> <li><p>проверьте, если это ios 7.</p></li> <li><p>установите содержимое строки состояния белым, в отличие от uistatusbarstyledefault.</p></li> <li><p>избегайте появления подпредставлений, чьи рамки выходят за видимые границы (для видов, анимируемых в основной вид сверху).</p></li> <li><p>создайте иллюзию, что строка состояния занимает место, как в ios 6, сместив и изменив размер окна приложения.</p></li> </ol><p><br></p><h2>для приложений с поворотом экрана</h2><p>используйте nsnotificationcenter для обнаружения изменений ориентации путем добавления</p><pre><code>[[nsnotificationcenter defaultcenter] addobserver:self selector:@selector(applicationdidchangestatusbarorientation:) name:uiapplicationdidchangestatusbarorientationnotification object:nil]; </code></pre><p>в <code>if (nsfoundationversionnumber > nsfoundationversionnumber\_ios\_6\_1)</code> и создайте новый метод в appdelegate:</p><pre><code>- (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); } } </code></pre><p>чтобы при изменении ориентации он вызывал оператор switch для определения ориентации экрана приложения («портрет», «перевернутый вниз», «пейзаж влево» или «пейзаж вправо») и соответственно изменял рамку окна приложения, создавая иллюзию строки состояния ios 6.</p><p><br></p><h2>чтобы изменить цвет фона строки состояния:</h2><p>добавлять</p><pre><code> @property (retain, nonatomic) uiwindow *background; </code></pre><p>в <code>appdelegate.h</code>, чтобы сделать <code>background</code> свойством в вашем классе и предотвратить его освобождение arc. (вам не нужно делать это, если вы не используете arc.)</p><p>после этого вам просто нужно создать uiwindow в <code>if (nsfoundationversionnumber > nsfoundationversionnumber\_ios\_6\_1)</code>:</p><pre><code>background = [[uiwindow alloc] initwithframe: cgrectmake(0, 0, self.window.frame.size.width, 20)]; background.backgroundcolor =[uicolor redcolor]; [background sethidden:no]; </code></pre><p>не забудьте <code>@synthesize background;</code> после <code>@implementation appdelegate</code>!</p>

<blockquote> <p><strong>обновление (новое решение)</strong> </p> <p>это обновление является лучшим решением проблемы с панелью навигации ios 7. вы можете установить пример цвета панели навигации: fakenavbar.backgroundcolor = [uicolor redcolor];</p> <p>примечание. если вы используете контроллер навигации по умолчанию, используйте старое решение.</p> <p><strong>appdelegate.m</strong></p> </blockquote><pre><code>- (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; } </code></pre><blockquote> <p><strong>old solution - если вы используете предыдущий код, пожалуйста, игнорируйте следующий код и изображение</strong> </p> <p><del>это старая версия решения для панели навигации ios 7.</del></p> </blockquote><p><del>я решил проблему с помощью следующего кода. это для добавления строки состояния . didfinishlaunchingwithoptions</del></p><pre><code>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]; } </code></pre><p><del>а для <a href="http://en.wikipedia.org/wiki/interface\_builder">interface builder</a> это для того, когда вы открываете с ios 6; это начинается с 0 пикселей.</del></p><del> примечание. дельты ios 6/7 отображаются только в том случае, если вы сняли флажок «использовать автоматическое расположение» для контроллера представления в «инспекторе файлов» (крайний левый значок) в области сведений.</del><p><img src="https://i.stack.imgur.com/qa800.png" alt="enter image description here"></p>

<p>решение :</p><p>установите его в вашем viewcontroller или в rootviewcontroller, переопределив метод:</p><pre><code>-(bool) prefersstatusbarhidden { return yes; } </code></pre>

<p>вот еще один подход для проектов, которые широко используют раскадровку:</p><p><strong> цель: </strong></p><p>цель этого подхода - воссоздать тот же стиль строки состояния в ios7, который был в ios6 (см. заголовок вопроса «строка состояния ios 7 вернуться к стилю ios 6?»).</p><p><strong> резюме: </strong></p><p>чтобы добиться этого, мы максимально используем раскадровку, смещая элементы пользовательского интерфейса, которые перекрываются строкой состояния (под ios 7), вниз, в то время как с помощью дельт-страниц можно отменить изменение макета вниз для ios 6.1 или более ранней версии. получающееся дополнительное пространство в ios 7 затем занято uiview с backgroundcolor, установленным в цвет по нашему выбору. последний может быть создан в коде или с использованием раскадровки (см. альтернативы ниже)</p><p><strong> предположения: </strong></p><p>чтобы получить желаемый результат при выполнении следующих шагов, предполагается, что для <code>view controller-based status bar appearance</code> задано значение no, а для <code>status bar style</code> установлено значение «прозрачный черный стиль (альфа из 0,5)» или «непрозрачный черный стиль». обе настройки можно найти/или добавить в разделе «информация» в настройках вашего проекта.</p><p><strong> шаги: </strong></p><ul> <li><p>добавьте в uiwindow подпредставление, которое будет использоваться в качестве фона строки состояния. для этого добавьте следующее в <code>application: didfinishlaunchingwithoptions:</code> вашего appdelegate после <code>makekeyandvisible</code></p> <pre><code>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]; } </code></pre></li> <li><p>поскольку вы программно добавили фон только для ios 7, вам придется соответствующим образом настроить макет элементов пользовательского интерфейса, которые перекрываются строкой состояния, при этом сохраняя их макет для ios6. для этого сделайте следующее:</p> <ul> <li>убедитесь, что <code>use autolayout</code> не отмечен для вашей раскадровки (это потому, что в противном случае «ios 6/7 deltas» не отображается в инспекторе размеров). сделать это: <ul> <li>выберите файл раскадровки</li> <li>показать коммунальные услуги</li> <li>выберите «показать инспектор файлов»</li> <li>под «документом интерфейсного разработчика» снимите флажок «использовать autolayout»</li> </ul></li> <li>по желанию, чтобы помочь вам отслеживать изменения макета для ios 7 и 6 по мере их применения, выберите «помощник редактора», выберите «предварительный просмотр» и «ios 6.1 или более ранняя версия»: <img src="https://i.stack.imgur.com/3jcgc.png" alt="enter image description here"> <img src="https://i.stack.imgur.com/ki8xg.png" alt="enter image description here"></li> <li>теперь выберите элемент пользовательского интерфейса, который вы хотите настроить, чтобы он больше не перекрывался строкой состояния.</li> <li>выберите «показать инспектор размера» в столбце «утилиты».</li> <li>переместите ваш элемент пользовательского интерфейса вдоль оси y на ту же величину, что и в строке состояния bg height: <img src="https://i.stack.imgur.com/n5sds.png" alt="enter image description here"></li> <li>и измените значение ios6/7 deltas для y на ту же отрицательную величину, что и высота bg строки состояния (обратите внимание на изменение в предварительном просмотре ios 6, если вы его используете): <img src="https://i.stack.imgur.com/doxho.png" alt="enter image description here"></li> </ul></li> </ul><p><strong> альтернативы: </strong></p><p>чтобы добавить еще меньше кода в проекты, насыщенные раскадровкой, и иметь автоматический фоновый режим строки состояния, вместо программного добавления фона для строки состояния, вы можете добавить цветное представление к каждому контроллеру представления, который находится в самом верху основного представления указанного viewcontroller. затем вы изменили бы дельту высоты этого нового вида на ту же отрицательную величину, что и высота вашего вида (чтобы она исчезла в ios 6).</p><p>недостатком этой альтернативы (хотя, возможно, она и незначительна, учитывая совместимость с автоматическим поворотом) является тот факт, что этот дополнительный вид не сразу виден, если вы просматриваете раскадровку для ios 6. вы бы знали, что он есть, только если вы посмотрите на " схема документа "раскадровка.</p>

<p>если вы не хотите, чтобы ваши контроллеры представления перекрывались строкой состояния (и панелями навигации), снимите флажок «расширить края под верхними панелями» в <a href="http://en.wikipedia.org/wiki/interface\_builder">интерфейсном разработчике</a> in <a href="http://en.wikipedia.org/wiki/xcode">xcode</a> 5.</p><p><img src="https://i.stack.imgur.com/lbssz.png" alt="uncheck the extend edges under top bars"></p>

<p>apple выпустила <em> <a href="https://developer.apple.com/library/content/qa/qa1797/\_index.html">технические вопросы и ответы qa1797: предотвращение того, чтобы строка состояния закрывала ваши представления</a> </em>. он отлично работает для версий ios 6 и ios 7.</p>

<p>я просмотрел много-много-много-много уроков, чтобы решить эту чертову проблему. но ни один из них не работает! вот мое решение, и оно работает для меня:</p><pre><code>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; } } </code></pre><p>логика проста. я перевожу взгляды всех детей на self.view с 20 пикселями .... вот и все. затем скриншот будет отображаться так же, как в ios 6. я ненавижу строку состояния ios7! ~ "~</p>

<p>небольшая альтернатива ответу арчи холта, немного более простая:</p><p>а. установите <code>uiviewcontrollerbasedstatusbarappearance</code> в <code>no</code> в info.plist</p><p>б. в <code>appdelegate</code>'s <code>application:didfinishlaunchingwithoptions:</code>, позвоните:</p><pre><code>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]; } </code></pre><p>и добавьте метод:</p><pre><code>- (void)applicationdidchangestatusbarorientationnotification:(nsnotification *)notification { // handling statusbar (ios7) self.window.frame = [uiscreen mainscreen].applicationframe; } </code></pre><p>вы также можете рассмотреть возможность создания подкласса <code>uiwindow</code> для обработки самого <code>uiapplicationdidchangestatusbarorientationnotification</code>. </p>

<p>я использовал это во всех моих контроллерах представления, это просто ... добавить эти строки во все ваши методы viewdidload:</p><pre><code>- (void)viewdidload{ //add this 2 lines: if ([self respondstoselector:@selector(edgesforextendedlayout)]) self.edgesforextendedlayout = uirectedgenone; [super viewdidload]; } </code></pre>

<p><strong> <h2>попробуйте этот простой метод ....</h2> </strong></p><p><strong> шаг 1 </strong>: чтобы изменить в одном <code>viewcontroller</code></p><pre><code>[[uiapplication sharedapplication] setstatusbarstyle: uistatusbarstyleblackopaque]; </code></pre><hr><p><strong> шаг 2 </strong>: изменить во всем приложении</p><pre><code>info.plist ----> status bar style --->uistatusbarstyle to uistatusbarstyleblackopaque </code></pre><hr><p><strong> шаг 3 </strong>: также добавьте это в каждую <code>viewwillappear</code>, чтобы настроить <code>statusbar</code> высоту для <code>ios7</code></p><pre><code> [[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]; } </code></pre>

<p>я достиг строки состояния, как ios 6 в ios 7.</p><p>установите для uiviewcontrollerbasedstatusbarappearance значение no в info.plist</p><p>передать этот код в метод <code>- (bool)application:(uiapplication *)application didfinishlaunchingwithoptions:(nsdictionary *)launchoptions</code> </p><pre><code>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); } </code></pre><p>он может отодвинуть все ваши просмотры на 20 пикселей. чтобы прийти, используйте следующий код в методе <code>-(void)viewdidappear:(bool)animated</code></p><pre><code>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; } </code></pre><p>вы должны установить значение windowheight userdefaults после выделения окна в методе didfinishlauncing, например: </p><pre><code>self.window = [[uiwindow alloc] initwithframe:[[uiscreen mainscreen] bounds]]; [[nsuserdefaults standarduserdefaults] setfloat:self.window.frame.size.height forkey:@"windowheight"]; </code></pre>

<p>в интерфейсном разработчике есть опция, которая вызывает свойство ios 6/7 delta, которое направлено на решение проблемы смещения.</p><p>взгляните на это в вопросе переполнения стека <em> <a href="https://stackoverflow.com/questions/17794037/interface-builder-what-are-the-uiviews-layout-ios-6-7-deltas-for/18744952#18744952">интерфейсный конструктор: для чего нужны uiview layout ios 6/7 delta?</a> </em>.</p>

<p>если вы используете конструктор интерфейса, попробуйте это:</p><p>в вашем xib-файле:</p><p><strong>1) выберите основной вид, установите цвет фона на черный (или любой другой цвет, который вы хотите, чтобы строка состояния была</strong></p><p><strong>2) убедитесь, что фон является автономным подпредставлением, расположенным как дочерний элемент верхнего уровня представления контроллера.</strong><br> переместите фон, чтобы стать прямым потомком зрения контроллера. проверьте панель автоматического изменения размера, чтобы убедиться, что вы заблокировали все края рамки, активировали обе оси гибкости, и, если это uiimageview, установите для режима содержимого значение масштаб для заполнения. программно это преобразуется в contentmode, установленный в uiviewcontentmodescaletofill, и имеет его маску автоматического изменения размера (uiviewautoresizingf flexiblewidth | uiviewautoresizingf flexheight).</p><p><strong>3) теперь переместите все, что заблокировано, сверху вниз - на 20 пунктов и установите для ios 6/7 delta y значение -20.</strong><br> все дочерние элементы верхнего уровня, которые привязаны к верхнему фрейму на панели автоматического изменения размера, должны быть сдвинуты на 20 пунктов вниз, а их ios 6/7 delta y должна быть установлена на -20. (cmd выберите все из них и нажмите стрелку вниз 20 раз - есть ли лучший способ для кого-либо?)</p><p><strong>4) отрегулируйте высоту ios 6/7 для всех вышеперечисленных элементов, которые имели гибкую высоту.</strong> для любого из элементов, которые были заблокированы в верхней и нижней части рамки и для которых была включена гибкая высота на панели автоматического изменения размера, также должна быть установлена высота треугольника ios 6/7, равная 20. это включает фоновое представление, упомянутое выше. это может показаться антиинтуитивным, но из-за порядка, в котором они применяются, это необходимо. сначала задается высота кадра (в зависимости от устройства), затем применяются дельты, и, наконец, маски авторазмера применяются на основе позиций смещения всех дочерних кадров - подумайте немного, это будет иметь смысл.</p><p><strong>5) наконец, элементы, которые были привязаны к нижней рамке, но не к верхней рамке, вообще не нуждаются в дельтах.</strong> </p><p>это даст вам одинаковую строку состояния в ios7 и ios6.</p><p>с другой стороны, если вы <em>хотите</em> стилизовать ios7 при сохранении совместимости с ios6, то установите значения дельта-y/дельта-высоты на 0 для фона.</p><p>чтобы увидеть больше информации о переходе на ios7, прочитайте полный пост: <a href="http://uncompiled.blogspot.com/2013/09/legacy-compatible-offsets-in-ios7.html">http://uncompiled.blogspot.com/2013/09/legacy-compatible-offsets-in-ios7.html</a> </p>

<p>это может быть огромной проблемой, если вы используете auto layout, потому что вы больше не можете напрямую манипулировать кадрами. есть простое решение без лишней работы.</p><p>я закончил тем, что написал служебный метод в utility class и вызвал его из метода <code>viewdidlayoutsubviews</code> всех контроллеров представления.</p><pre><code>+ (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]; } } </code></pre><p>переопределите ваш метод <code>viewdidlayoutsubviews</code> в контроллере представления, где вы хотите строку состояния. это поможет вам пережить бремя автопутешествий.</p><pre><code>- (void)viewdidlayoutsubviews { [[uiapplication sharedapplication]setstatusbarstyle:uistatusbarstylelightcontent]; [super viewdidlayoutsubviews]; [myutilityclass addstatusbarifios7:self]; } </code></pre>

<p>мое решение состояло в том, чтобы добавить <code>uiview</code> с высотой 20 точек поверх окна, когда на ios 7 . затем я создал метод в своем классе appdelegate, чтобы показать/скрыть «сплошной» фон строки состояния. в <code>application:didfinishlaunchingwithoptions:</code>:</p><pre><code>// ... // 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; </code></pre><p>затем я создал метод постепенного увеличения/уменьшения черного фона строки состояния:</p><pre><code>- (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; } }]; } </code></pre><p>все, что мне нужно сейчас сделать, это вызвать <code>[appdelegate showsolidstatusbar:yes]</code>, когда это необходимо.</p>

<p>самый простой способ сделать это - установить старый sdk на свой новейший xcode.</p><p>как установить более старый sdk на новейший xcode?</p><ol> <li><p>вы можете получить ios 6.1 sdk с <a href="http://www.4shared.com/zip/nlpgsxz6/iphoneos61sdk.html">http://www.4shared.com/zip/nlpgsxz6/iphoneos61sdk.html</a> или загрузить более старый xcode и получить sdk из его содержимого.</p></li> <li><p>разархивируйте и вставьте эту папку в /applications/xcode.app/contents/developer/platforms/iphoneos.platform/developer/sdks</p></li> <li><p>перезапустите xcode.</p></li> <li>теперь вы можете выбрать более старый sdk в настройках вашего проекта.</li> </ol><p>надеюсь, это поможет вам. у меня это сработало =)</p>

<p>я опоздал на этот ответ, но я просто хочу поделиться тем, что я сделал, что в принципе самое простое решение</p><p>прежде всего -> перейдите к своему файлу <code>info.plist</code> и<strong> добавьте стиль строки состояния-> прозрачный черный стиль (альфа 0,5) </strong></p><p>теперь вот оно:</p><p><strong> добавьте этот код в свой appdelegate.m </strong></p><pre><code>- (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; } </code></pre>

<p>так как использование <code>presentviewcontroller:animated:completion:</code> испортило <code>window.rootviewcontroller.view</code>, мне пришлось искать другой подход к этой проблеме. наконец-то я получил его для работы с модалами и вращениями, создав подкласс uiview моего rootviewcontroller.</p><p>.час</p><pre><code>@interface rootview : uiview @end </code></pre><p>.m</p><pre><code>@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 </code></pre><p>теперь у вас есть хороший обходной путь для анимации ios7.</p>

<p>это может быть слишком поздно, чтобы поделиться, но у меня есть кое-что, что могло бы помочь кому-то, я пытался подразделить uinavigationbar и хотел сделать его похожим на ios 6 с черной строкой состояния и текстом строки состояния в белом.</p><p>вот что я нашел для этого</p><pre><code> self.navigationcontroller?.navigationbar.clipstobounds = true self.navigationcontroller?.navigationbar.translucent = false self.navigationcontroller?.navigationbar.barstyle = .black self.navigationcontroller?.navigationbar.bartintcolor = uicolor.whitecolor() </code></pre><p>это сделало мой фон строки состояния черным, текст строки состояния белым и цвет панели навигации белым.</p><p>ios 9.3, xcode 7.3.1</p>

<p>чтобы продолжить работу с setstatusbarhidden: я использую эту категорию:</p><pre><code>@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 </code></pre>

<p>мое очень простое решение (при условии, что поддерживается только вертикальная ориентация) состоит в том, чтобы переопределить границы окна приложения для версий ios ниже 7, в методе делегата приложения didfinishlaunchingwithoptions:</p><pre><code>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]; } </code></pre>

<p>вы можете скрыть строку состояния все вместе. так что ваше приложение будет полноэкранным. я думаю, что это лучшее, что вы получите.</p><p><code>uistatusbarstylenone</code> или установите в настройках цели.</p>

<p>шаги для скрытия строки состояния в ios 7:</p><p>1. перейдите в файл приложения info.plist.</p><p>2.и установить, просмотреть внешний вид строки состояния контроллера: boolean no </p><p>надеюсь, я решил проблему со статусной строкой .....</p>

<p>я нашел здесь лучшие альтернативы и решения для этой проблемы панели навигации в ios7!</p><p> <a href="http://www.appcoda.com/customize-navigation-status-bar-ios-7/">http://www.appcoda.com/customize-navigation-status-bar-ios-7/</a> </p><p>я надеюсь, что это очистит все наши вопросы и заботы. </p>