строка состояния и панель навигации отображаются за пределами моего представления в ios 7

<p>я недавно загрузил <a href="http://en.wikipedia.org/wiki/xcode">xcode</a> 5 dp, чтобы протестировать свои приложения в ios 7. первое, что я заметил и подтвердил, это то, что границы моего представления не всегда изменяются с учетом строки состояния и панели навигации.</p><p>в <code>viewdidlayoutsubviews</code> я печатаю границы представления:</p><blockquote> <p>{{0, 0}, {320, 568}}</p> </blockquote><p>в результате мой контент появляется под панелью навигации и строкой состояния.</p><p>я знаю, что мог бы сам учесть высоту, получив высоту основного экрана, вычтя высоту строки состояния и высоту панели навигации, но это кажется ненужной дополнительной работой.</p><p>как я могу исправить эту проблему?</p><p><strong> update: </strong></p><p>я нашел решение для этой конкретной проблемы. установите для полупрозрачного свойства панели навигации значение no:</p><pre><code>self.navigationcontroller.navigationbar.translucent = no; </code></pre><p>это предотвратит отображение вида под панелью навигации и строкой состояния.</p><p>однако я не нашел исправления для случая, когда вы хотите, чтобы панель навигации была полупрозрачной. например, при просмотре фотографии в полноэкранном режиме, я хочу, чтобы навигационная панель была полупрозрачной, а вид под ней был обрамлен. это работает, но когда я переключаю показ/скрытие панели навигации, я получаю еще более странные результаты. первое подпредставление (uiscrollview) получает свои границы y origin каждый раз меняется.</p>

<p>вы можете добиться этого, внедрив новое свойство <code>edgesforextendedlayout</code> в ios7 sdk. пожалуйста, добавьте следующий код для достижения этой цели,</p><pre><code>if ([self respondstoselector:@selector(edgesforextendedlayout)]) self.edgesforextendedlayout = uirectedgenone; </code></pre><p>вы должны добавить вышеупомянутое в вашем методе <code>-(void)viewdidload</code>.</p><blockquote> <p>в ios 7 внесены некоторые изменения в макет и настройку внешнего вида вашего <em>ui</em>. изменения в макете контроллера представления, цвете оттенка и шрифте влияют на все <em> объекты uikit </em> в вашем приложении. кроме того, усовершенствования api распознавания жестов дают вам более точный контроль над взаимодействиями жестов.</p> <p><strong> использование контроллеров представления </strong></p> <p>в ios 7 контроллеры представления используют полноэкранное расположение. в то же время, ios 7 дает вам более детальный контроль над тем, как контроллер представления размещает свои представления. в частности, концепция полноэкранного макета была усовершенствована, чтобы позволить контроллеру представления определять макет каждого края своего представления.</p> <p>свойство контроллера представления <code>wantsfullscreenlayout</code> устарело в ios 7. если вы в настоящий момент указываете <code>wantsfullscreenlayout = no</code>, контроллер представления может отображать свое содержимое в неожиданном месте экрана при запуске в ios 7.</p> <p>чтобы настроить, как контроллер представления размещает свои представления, <code>uiviewcontroller</code> предоставляет следующие свойства:</p> <ul> <li><strong> edgesforextendedlayout </strong></li> </ul> <p>свойство <code>edgesforextendedlayout</code> использует тип <code>uirectedge</code>, который определяет каждое из четырех ребер прямоугольника в дополнение к указанию none и all. используйте <code>edgesforextendedlayout</code>, чтобы указать, какие края вида должны быть расширены, независимо от прозрачности полосы. по умолчанию значением этого свойства является <code>uirectedgeall</code>.</p> <ul> <li><strong> extendedlayoutincludesopaquebars </strong></li> </ul> <p>если в вашем дизайне используются непрозрачные столбцы, уточните <code>edgesforextendedlayout</code>, также задав для свойства <code>extendedlayoutincludesopaquebars</code> значение <strong>no</strong>. (значение по умолчанию <code>extendedlayoutincludesopaquebars</code>: <strong>нет</strong>.)</p> <ul> <li><strong> automaticallyadjustsscrollviewinsets </strong></li> </ul> <p>если вы не хотите, чтобы вставки содержимого представления прокрутки автоматически настраивались, установите для <code>automaticallyadjustsscrollviewinsets</code> значение <strong>нет</strong>. (значение по умолчанию <code>automaticallyadjustsscrollviewinsets</code>: <strong>yes</strong>.)</p> <ul> <li><strong> toplayoutguide, bottomlayoutguide </strong></li> </ul> <p>свойства <code>toplayoutguide</code> и <code>bottomlayoutguide</code> указывают расположение верхних или нижних краев панели в представлении контроллера представления. если столбцы должны перекрывать верхнюю или нижнюю часть представления, вы можете использовать interface builder для позиционирования представления относительно панели, создавая ограничения в нижней части <code>toplayoutguide</code> или в верхней части bottomlayoutguide. (если ни один столбец не должен перекрывать представление, нижняя часть <code>toplayoutguide</code> совпадает с верхней частью представления, а верхняя часть <code>bottomlayoutguide</code> совпадает с нижней частью представления.) оба свойства создаются по запросу, когда их запрашивают.</p> </blockquote><p>пожалуйста, обратитесь <a href="https://developer.apple.com/library/prerelease/ios/documentation/userexperience/conceptual/transitionguide/appearancecustomization.html#//apple\_ref/doc/uid/tp40013174-ch15-sw1">apple doc</a> </p>

<p>вам не нужно вычислять, как далеко все сдвинуть вниз, для этого есть встроенное свойство. в интерфейсном разработчике выделите ваш контроллер представления, а затем перейдите к инспектору атрибутов. здесь вы увидите несколько флажков со словами "расширить края". как вы можете видеть, на первом скриншоте выбор по умолчанию - отображение контента под верхней и нижней полосами, а не под непрозрачными полосами, поэтому настройка стиля полосы на непрозрачный работает для вас.</p><p>как вы можете увидеть на первом скриншоте, под панелью навигации скрываются два элемента пользовательского интерфейса. (я включил каркасы в ib, чтобы проиллюстрировать это). эти элементы, uibutton и uisegmentedcontrol, имеют свой "y" origin, установленный в ноль, и контроллер представления установлен так, чтобы разрешить контент ниже верхней панели.</p><p><img src="https://i.stack.imgur.com/rlc4s.png" alt="enter image description here"></p><p>этот второй снимок экрана показывает, что происходит, когда вы снимаете флажок "under top bars". как вы можете видеть, представление контроллеров представления было смещено соответствующим образом, чтобы его y origin находился прямо под панелью навигации.</p><p><img src="https://i.stack.imgur.com/zykix.png" alt="enter image description here"></p><p>это также может быть достигнуто программным путем с помощью <code>-[uiviewcontroller edgesforextendedlayout]</code>. вот ссылка на ссылку на класс для <a href="https://developer.apple.com/library/prerelease/ios/documentation/uikit/reference/uiviewcontroller\_class/reference/reference.html#//apple\_ref/occ/instp/uiviewcontroller/edgesforextendedlayout">edgeforextendedlayout</a> и для <a href="https://developer.apple.com/library/prerelease/ios/documentation/uikit/reference/uikitconstantsreference/reference/reference.html#//apple\_ref/c/tdef/uirectedge">irectedge</a> </p><pre><code>[self setedgesforextendedlayout:uirectedgenone]; </code></pre>

<p>я создал свой вид программно, и это сработало для меня:</p><pre><code>- (void) viewdidlayoutsubviews { // only works for ios 7+ if ([[[uidevice currentdevice] systemversion] floatvalue] >= 7.0) { cgrect viewbounds = self.view.bounds; cgfloat topbaroffset = self.toplayoutguide.length; // snaps the view under the status bar (ios 6 style) viewbounds.origin.y = topbaroffset * -1; // shrink the bounds of your view to compensate for the offset viewbounds.size.height = viewbounds.size.height + (topbaroffset * -1); self.view.bounds = viewbounds; } } </code></pre><p> <a href="https://developer.apple.com/library/ios/documentation/uikit/reference/uiviewcontroller\_class/uiviewcontroller\_class.pdf">источник</a> (в <strong> разделе toplayoutguide </strong> внизу страницы 39).</p>

<p>решение swift 3/swift 4, которое также работает с файлами nib/xib в ios 10+:</p><pre><code>override func viewdidload() { super.viewdidload() edgesforextendedlayout = [] } </code></pre>

<p>если вы хотите, чтобы у представления была полупрозрачная навигационная панель (что-то вроде nice), вы должны установить contentinset или подобное.</p><p>вот как я это делаю:</p><pre><code>// check if we are running on ios7 if([[[[uidevice currentdevice] systemversion] componentsseparatedbystring:@"."][0] intvalue] >= 7) { cgrect statusbarviewrect = [[uiapplication sharedapplication] statusbarframe]; float heightpadding = statusbarviewrect.size.height+self.navigationcontroller.navigationbar.frame.size.height; mycontentview.contentinset = uiedgeinsetsmake(heightpadding, 0.0, 0.0, 0.0); } </code></pre>

<p>в вашем plist-файле приложения добавьте строку, назовите ее "просмотр внешнего вида строки состояния на основе контроллера" и установите для нее значение <em>no</em>.</p>

<p><code>edgesforextendedlayout</code> справляется с задачей ios 7. однако, если вы соберете приложение в ios 7 sdk и развернете его в ios 6, панель навигации будет полупрозрачной, а виды будут отображаться под ней. итак, чтобы исправить это как для ios 7, так и для ios 6, сделайте следующее:</p><pre><code>self.navigationcontroller.navigationbar.barstyle = uibarstyleblackopaque; if ([self respondstoselector:@selector(edgesforextendedlayout)]) self.edgesforextendedlayout = uirectedgenone; // ios 7 specific </code></pre>

<p>самый простой трюк - открыть файл <a href="https://en.wikipedia.org/wiki/interface\_builder">nib</a> и выполнить два простых шага:</p><ol> <li>просто переключите это и установите тот, который вы предпочитаете:</li> </ol><p><img src="https://i.stack.imgur.com/aedfe.png" alt="enter image description here"></p><ol start="2"> <li>выберите те uiview/uiimageview/..., которые вы хотите переместить вниз. в моем случае только логотип был перекрыт, и я установил дельту на +15; (или -15, если вы выбрали ios 7 на шаге 1)</li> </ol><p><img src="https://i.stack.imgur.com/pdeam.jpg" alt="enter image description here"></p><p>и <strong> результат </strong>:</p><p><img src="https://i.stack.imgur.com/tckdb.png" alt="before"> <img src="https://i.stack.imgur.com/jpkpy.png" alt="after"></p>

<p>быстрое решение:</p><pre><code>override func viewwillappear(animated: bool) { super.viewwillappear(animated) self.edgesforextendedlayout = uirectedge.none } </code></pre>

<p><strong>swift</strong></p><pre><code>override func viewwillappear(\_ animated: bool) { self.edgesforextendedlayout = [] } </code></pre>

<p>я хотел бы расширить ответ stunner и добавить оператор <code>if</code>, чтобы проверить, является ли это ios-7, потому что, когда я тестировал его на ios 6, мое приложение зависало.</p><p>дополнение будет добавлять:</p><pre><code>if ([[[uidevice currentdevice] systemversion] floatvalue] >= 7.0) </code></pre><p>поэтому я бы предложил добавить этот метод в ваш файл <code>myviewcontroler.m</code>:</p><pre><code>- (void) viewdidlayoutsubviews { if ([[[uidevice currentdevice] systemversion] floatvalue] >= 7.0) { cgrect viewbounds = self.view.bounds; cgfloat topbaroffset = self.toplayoutguide.length; viewbounds.origin.y = topbaroffset * -1; self.view.bounds = viewbounds; } } </code></pre>

<p>у меня есть сценарий, в котором я использую bannerviewcontroller, написанный apple для отображения моих объявлений, и scrollviewcontroller, встроенный в bannerviewcontroller.</p><p>чтобы панель навигации не скрывала мой контент, мне пришлось внести два изменения.</p><p>1) изменить bannerviewcontroller.m</p><pre><code>- (void)viewdidload { [super viewdidload]; float systemversion = [[[uidevice currentdevice] systemversion] floatvalue]; if (systemversion >= 7.0) { self.edgesforextendedlayout = uirectedgenone; } } </code></pre><p>2) изменить мой scrollviewcontoller</p><pre><code>- (void)viewdidload { [super viewdidload]; float systemversion = [[[uidevice currentdevice] systemversion] floatvalue]; if (systemversion >= 7.0) { self.edgesforextendedlayout = uirectedgebottom; } } </code></pre><p>теперь реклама правильно отображается в нижней части окна, а не закрывается панелью навигации, а содержимое вверху не обрезается.</p>

<p>сделать ограничения для top layout, как это <a href="https://i.stack.imgur.com/m7gma.png"><img src="https://i.stack.imgur.com/m7gma.png" alt="enter image description here"></a> </p>

<p>просто установите следующий код в поле зрения появится.</p><pre><code> if ([[[uidevice currentdevice] systemversion] floatvalue]<= 7) { self.edgesforextendedlayout = uirectedgenone; } </code></pre>

<p>для меня самое простое решение - добавить два ключа в список.</p><p><img src="https://i.stack.imgur.com/74ioq.png" alt="enter image description here"></p>

<p>swift 4.2 - xcode 10.0 - ios 12.0:</p><pre><code>if #available(ios 11.0, *) {} else { self.edgesforextendedlayout = [] self.navigationcontroller?.view.backgroundcolor = .white } </code></pre>

<p>добавьте ключ "просмотреть внешний вид строки состояния на основе контроллера" из выпадающего списка в виде строки в <code>info.plist</code>. что-то вроде этого:<br></p><p><img src="https://i.stack.imgur.com/endt2.png" alt="enter image description here"></p>

<p>у меня была та же проблема с моим приложением на ipad (armv7, armv7s, amr64) только при представлении другого uiviewcontroller, и после их отклонения появляется панель навигации под строкой состояния ... я трачу много времени, чтобы найти какое-либо решение для этого. я использую раскадровку и в interfacebuilder для uiviewcontroller, который делает ужасно, я устанавливаю презентацию из fullscreen -> current context, и это решает эту проблему. это работает в моем приложении только для ipad => ios8.0 (тестирование с ios8.1) и для ipad с ios 7.1 не работает !! <img src="https://i.stack.imgur.com/feuwt.png" alt="see screenshot"></p>

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

<p>в моем случае прерывание loadview ()<br> этот код: self.edgesforextendedlayout = uirectedgenone</p><p>но после удаления loadview () все работало нормально</p>