it-swarm.com.ru

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

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

В viewDidLayoutSubviews я печатаю границы представления:

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

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

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

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

Update:

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

self.navigationController.navigationBar.translucent = NO;

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

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

432
beebcon

Вы можете добиться этого, внедрив новое свойство edgesForExtendedLayout в iOS7 SDK. Пожалуйста, добавьте следующий код для достижения этой цели,

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

Вы должны добавить вышеупомянутое в вашем методе -(void)viewDidLoad.

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

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

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

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

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

  • edgesForExtendedLayout

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

  • extendedLayoutIncludesOpaqueBars

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

  • automaticallyAdjustsScrollViewInsets

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

  • topLayoutGuide, bottomLayoutGuide

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

Пожалуйста, обратитесь Apple Doc

494
Nandha

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

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

enter image description here

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

enter image description here

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

[self setEdgesForExtendedLayout:UIRectEdgeNone];
110
Mick MacCallum

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

- (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).

33
Stunner

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

override func viewDidLoad() {
    super.viewDidLoad()

    edgesForExtendedLayout = []
}
26
flo_23

Если вы хотите, чтобы у представления была полупрозрачная навигационная панель (что-то вроде Nice), вы должны установить 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);
}
10
Magnus

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

9
Idan

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
9
Raj Pawan Gumdal

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

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

Enter image description here

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

Enter image description here

И результат :

BeforeAfter

7
Riskov

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

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

Swift

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

Я хотел бы расширить ответ 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;
    }
}
4
werdsackjon

У меня есть сценарий, в котором я использую 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;
    }
}

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

3
Xavier John

сделать ограничения для Top Layout, как это enter image description here

2
carmen_munich

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

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

Для меня самое простое решение - добавить два ключа в список.

enter image description here

1
giuseppe

Swift 4.2 - Xcode 10.0 - iOS 12.0:

if #available(iOS 11.0, *) {} else {
  self.edgesForExtendedLayout = []
  self.navigationController?.view.backgroundColor = .white
}
1
juliancadi

Добавьте ключ "Просмотреть внешний вид строки состояния на основе контроллера" из выпадающего списка в виде строки в info.plist. Что-то вроде этого:

Enter image description here

1
Kursat Turkay

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

1
Alexej W.

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

1. Перейдите в файл приложения info.plist.

2.И установить, просмотреть внешний вид строки состояния контроллера: Boolean NO

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

0
chandrika

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

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

0
DevB2F