Строка состояния и панель навигации отображаются по моим ограничениям просмотра в iOS 7

Недавно я загрузил Xcode 5 DP для тестирования моих приложений в iOS 7. Первое, что я заметил и подтвердил, - это то, что мои ограничения зрения не всегда изменяется для учета строки состояния и панели навигации.

В viewDidLayoutSubviews, я печатаю границы просмотра:

{{0, 0}, {320, 568}}

В результате мой контент появляется под панелью навигации и строкой состояния.

Я знаю, что сам мог учитывать высоту, получая высоту основного экрана, вычитая высоту строки состояния и высоту навигационной панели, но это кажется ненужной дополнительной работой.

Как я могу исправить эту проблему?

Update:

Я нашел решение для этой конкретной проблемы. Установите прозрачное свойство навигационной панели в положение NO:

self.navigationController.navigationBar.translucent = NO;

Это позволит зафиксировать представление под рамкой под панелью навигации и панель состояния.

Однако я не нашел исправления для случая, когда вы хотите, чтобы панель навигации была полупрозрачной. Например, просматривая полноэкранный режим фото, я хочу, чтобы прозрачная панель навигации была прозрачной, а вид под ней был обрамлен. Это работает, но когда я переключаю отображение/скрытие навигационной панели, я испытал еще более странные результаты. Первое подзадача (UIScrollView) получает свои границы, когда исходное значение изменяется каждый раз.

Ответ 1

Это можно реализовать, реализовав новое свойство edgesForExtendedLayout в iOS7 SDK. Чтобы достичь этого, добавьте следующий код,

if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
        self.edgesForExtendedLayout = UIRectEdgeNone;

Вам нужно добавить это в свой -(void)viewDidLoad метод.

iOS 7 содержит несколько изменений в том, как вы планируете и настраиваете внешний вид вашего пользовательского интерфейса. Изменения в макете диспетчера просмотра, оттенке цвет и шрифт влияют на все объекты UIKit в вашем приложении. В дополнение, усовершенствования API-интерфейсов распознавателя жестов дают вам более тонкие гранулированный контроль над взаимодействием жестов.

Использование контроллеров просмотра

В iOS 7 контроллеры просмотра используют полноэкранную компоновку. В то же время, iOS 7 дает вам более подробный контроль над тем, как контроллер вида излагает его взгляды. В частности, концепция полноэкранного макета был усовершенствован, чтобы позволить контроллеру вида определять макет каждого край его представления.

Свойство контроллера представления wantsFullScreenLayout устарело iOS 7. Если вы в настоящее время указываете wantsFullScreenLayout = NO, представление контроллер может отображать его содержимое в непредвиденном месте экрана когда он запускается в iOS 7.

Чтобы настроить, как контроллер вида отображает его виды, UIViewControllerпредоставляет следующие свойства:

  • edgesForExtendedLayout

Свойство edgesForExtendedLayout использует тип UIRectEdgeкоторый определяет каждый из четырех прямоугольников, в дополнение к не указав ни одного, ни другого. Используйте edgesForExtendedLayout, чтобы указать, какие края представления должны быть расширены, независимо от прозрачности штриха. От default, значение этого свойства равно UIRectEdgeAll.

  • extendedLayoutIncludesOpaqueBars

Если ваш дизайн использует непрозрачные полосы, уточните edgesForExtendedLayout на также устанавливая свойство extendedLayoutIncludesOpaqueBars NO. (Значение по умолчанию extendedLayoutIncludesOpaqueBars NO.)

  • automaticallyAdjustsScrollViewInsets

Если вы не хотите, чтобы прокрутки отображали вставки содержимого автоматически настроен, установите automaticallyAdjustsScrollViewInsets на НЕТ. (The значение по умолчанию automaticallyAdjustsScrollViewInsets YES.)

  • topLayoutGuide, bottomLayoutGuide

Свойства topLayoutGuide и bottomLayoutGuide указывают на расположение верхней или нижней границы бруса в представлении контроллеров вида. Если полосы должны перекрывать верх или низ представления, вы можете использовать Interface Builder, чтобы позиционировать представление относительно панели, создав ограничения в нижней части topLayoutGuide или в верхней части bottomLayoutGuide. (Если никакие полоски не должны перекрывать вид, нижняя часть topLayoutGuide - это то же самое, что и верхняя часть представления, а верхняя часть bottomLayoutGuide совпадает с нижней частью представления.) Оба свойства лениво создаются по запросу.

Пожалуйста, обратитесь, apple doc

Ответ 2

Вам не нужно рассчитать, как далеко сдвинуть все вниз, там есть свойство для этого. В Interface Builder выделите свой контроллер представлений и перейдите к инспектору атрибутов. Здесь вы увидите некоторые флажки рядом со словами "Расширить края". Как вы можете видеть, на первом снимке экрана выбор по умолчанию заключается в том, что контент отображается в верхнем и нижнем столбцах, но не под непрозрачными полосками, поэтому настройка стиля бара не будет полупрозрачным, работающим для вас.

Как вы можете видеть на первом снимке экрана, есть два элемента пользовательского интерфейса, скрывающиеся под панелью навигации. (Я включил каркасы в IB, чтобы проиллюстрировать это). Эти элементы, UIButton и UISegmentedControl имеют исходное значение "y", установленное на ноль, и контроллер представления настроен на разрешение содержимого под верхней панелью.

enter image description here

Этот второй снимок экрана показывает, что происходит, когда вы снимаете флажок "Under Top Bars". Как вы можете видеть, представление диспетчера представлений было смещено вниз соответствующим образом, чтобы его начало y находилось прямо под навигационной панелью.

enter image description here

Это также можно выполнить программно с помощью -[UIViewController edgesForExtendedLayout]. Здесь ссылка на ссылку класса для edgeForExtendedLayout и для UIRectEdge

[self setEdgesForExtendedLayout:UIRectEdgeNone];

Ответ 3

Я создал свое представление программно, и это закончилось для меня работой:

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

Источник (в разделе topLayoutGuide внизу страницы стр. 39).

Ответ 4

Решение Swift 3, которое также работает с файлами NIBs/XIB в iOS 10:

override func viewDidLoad() {
    super.viewDidLoad()

    edgesForExtendedLayout = []
}

Ответ 5

Если вы хотите, чтобы в представлении была полупрозрачная навигационная панель (что приятно), вам нужно настроить contentInset или подобное.

Вот как я это делаю:

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

Ответ 6

В вашем файле plist приложения добавьте строку, назовите его "Просмотр состояния панели управления на основе контроллера" и установите для него значение NO.

Ответ 7

edgesForExtendedLayout делает трюк для iOS 7. Однако, если вы создаете приложение через iOS 7 SDK и развертываете его в iOS 6, панель навигации выглядит полупрозрачной, а представления под ней. Итак, чтобы исправить это как для iOS 7, так и для iOS 6, выполните следующие действия:

self.navigationController.navigationBar.barStyle = UIBarStyleBlackOpaque;
if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
    self.edgesForExtendedLayout = UIRectEdgeNone;   // iOS 7 specific

Ответ 8

Самый простой трюк - открыть файл NIB и выполнить следующие два простых шага:

  • Просто переключите это и установите его в тот, который вы предпочитаете:

Enter image description here

  1. Выберите те UIView/UIIMageView/..., которые вы хотите удалить. В моем случае только логотип был перекрыт, я установил delta на +15; (OR -15, если вы выбрали iOS 7 на шаге 1)

Enter image description here

И результат:

BeforeAfter

Ответ 9

Я хотел бы расширить ответ Stunner и добавить оператор if, чтобы проверить, является ли это iOS-7, потому что когда я протестировал его на iOS 6, мое приложение потерпит крах.

Добавлением будет добавление:

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)

Поэтому я бы предложил добавить этот метод в ваш файл MyViewControler.m:

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

Ответ 10

Быстрое решение:

override func viewWillAppear(animated: Bool) {
    self.edgesForExtendedLayout = UIRectEdge.None
}

Ответ 11

У меня есть сценарий, когда я использую BannerViewController, написанный Apple, для показа моих объявлений и ScrollViewController, встроенных в BannerViewController.

Чтобы панель навигации не скрывала мой контент, мне пришлось внести два изменения.

1) Изменить BannerViewController.m

- (void)viewDidLoad
{
   [super viewDidLoad];
   float systemVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
   if (systemVersion >= 7.0) {
      self.edgesForExtendedLayout = UIRectEdgeNone;
   }
}

2) Измените мой ScrollViewContoller

- (void)viewDidLoad
{
    [super viewDidLoad];
    float systemVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
    if (systemVersion >= 7.0) {
        self.edgesForExtendedLayout = UIRectEdgeBottom;
    }
}

Теперь объявления отображаются правильно в нижней части представления, а не закрываются панелью навигации, а содержимое сверху не обрезается.

Ответ 12

Swift 3

override func viewWillAppear(_ animated: Bool) {
    self.edgesForExtendedLayout = []
}

Ответ 13

Добавьте в раскрывающийся список строку "Строка состояния на панели управления View Controller" в виде строки в info.plist. Что-то вроде этого:

Enter image description here

Ответ 14

Для меня самым простым решением является добавление двух клавиш в plist

enter image description here

Ответ 15

У меня была такая же проблема с моим приложением с помощью iPads (armv7, armv7s, amr64), только представив другой UIViewController, и после того, как они уволены, он переходит в навигационную панель в строке состояния... Я трачу много времени, чтобы найти решение для этого. Я использую раскадровку и в InterfaceBuilder для UIViewController, который делает ужасным установку Презентации из FullScreen → Current Context и исправляет эту проблему. Он работает в моем приложении только для iPads = > iOS8.0 (тестирование с iOS8.1), а для iPads с iOS 7.1 не работает! see screenshot

Ответ 16

просто установите следующий код в представлении.

  if ([[[UIDevice currentDevice] systemVersion] floatValue]<= 7) {
self.edgesForExtendedLayout = UIRectEdgeNone;
 }

Ответ 17

сделать ограничения для Top Layout, как это введите описание изображения здесь

Ответ 18

Шаги для скрытия строки состояния в iOS 7:

1.Вобходимо к файлу info.plist вашего приложения.

2.And Set, Просмотреть вид строки состояния на основе контроллера: Boolean NO

Надеюсь, я решил проблему с баром состояния.....

Ответ 19

В моем случае, когда loadView() прерван
этот код: self.edgesForExtendedLayout = UIRectEdgeNone

но после удаления loadView() все работало нормально