Пояснення різниці між автоматичноAdjustsScrollViewInsets, extensionLayoutIncludesOpaqueBars, edgeForExtendedLayout в iOS7


250

Я багато читав про перехід інтерфейсу інтерфейсу iOS7.

Я не можу отримати те , що ці три властивості automaticallyAdjustsScrollViewInsets, extendedLayoutIncludesOpaqueBars, edgesForExtendedLayout??

Наприклад, я намагаюся змусити мої контролери перегляду запуститися нижче рядка стану, але я не в змозі цього досягти.


5
і чому ви думаєте, що я не читав цього? .. Проблема в тому, що працює не так, як очікувалося, як і я не добре це зрозумів !! .. ось причина
user1010819

1
Ой, я неправильно зрозумів, що ти там говорив. Я не намагався звучати покровительською, просто коли деякі люди задають подібні запитання, і є новинками на сайті, вони пропускають очевидні рішення.
erdekhayser

8
У своєму методі viewDidLoad додайте if ([self respondsToSelector: @selector (edgeForExtendedLayout)]) self.edgesForExtendedLayout = UIRectEdgeNone; що змусить ваш погляд починати внизу рядка стану.
Нандха

Відповіді:


629

Починаючи з iOS7, контролери перегляду використовують за замовчуванням макет на весь екран. У той же час ви маєте більше контролю над тим, як він викладає свої погляди, і це робиться з тими властивостями:

edgeForExtendedLayout

В основному за допомогою цього властивості ви встановлюєте, які сторони вашого перегляду можна розширити, щоб охопити весь екран. Уявіть, що ви натискаєте UIViewControllerна a UINavigationController. Коли вигляд цього контролера перегляду буде викладений, він розпочнеться там, де закінчується панель навігації, але ця властивість визначатиме, які сторони огляду (верхній, лівий, нижній, правий) можна розширити, щоб заповнити весь екран.

Давайте подивимось це на прикладі:

UIViewController *viewController = [[UIViewController alloc] init];
viewController.view.backgroundColor = [UIColor redColor];
UINavigationController *mainNavigationController = [[UINavigationController alloc] initWithRootViewController:viewController];

Тут ви не встановлюєте значення edgesForExtendedLayout, тому значення за замовчуванням приймається ( UIRectEdgeAll), тому подання розширює його макет, щоб заповнити весь екран.

Це результат:

без країв для розширеного макета, вигляд заповнює весь екран

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

Тепер ви будете встановлювати це значення UIRectEdgeNone, тому ви скажете контролеру перегляду не розширювати подання на екран:

UIViewController *viewController = [[UIViewController alloc] init];
viewController.view.backgroundColor = [UIColor redColor];
viewController.edgesForExtendedLayout = UIRectEdgeNone;
UINavigationController *mainNavigationController = [[UINavigationController alloc] initWithRootViewController:viewController];

І результат:

із встановленими краямиForExtendedLayout, вигляд знаходиться лише під навігацією


автоматичноAdjustsScrollViewInsets

Ця властивість використовується , коли ваша точка зору є UIScrollViewабо подібними, ніби UITableView. Ви хочете, щоб ваша таблиця починалася там, де закінчується панель навігації, оскільки ви не бачите весь вміст, якщо ні, але в той же час ви хочете, щоб ваша таблиця охоплювала весь екран під час прокрутки. У такому випадку встановлення edgesForExtendedLayoutзначення None не працюватиме, оскільки ваша таблиця почне прокручуватися там, де закінчується панель навігації, і вона не буде йти за нею.

Ось, де ця властивість стане в нагоді, якщо ви дозволите контролеру перегляду автоматично налаштувати вставки (встановивши це властивість на ТАК, також значення за замовчуванням), воно додасть вставки вгорі таблиці, тому таблиця почне починатися з навігації смужка закінчується, але прокрутка охопить увесь екран.

Це коли встановлено значення NO:

таблиця прокручуватиметься на весь екран, але починає частково висвітлюватися

І ТАК (за замовчуванням):

таблиця прокручується по всьому екрану і починається прямо під навігацією

В обох випадках таблиця прокручується за панеллю навігації, але у другому випадку (ТАК) вона почне знизу навігаційної панелі.


extensionLayoutIncludesOpaqueBars

Це значення є лише доповненням до попередніх. За замовчуванням для цього параметра встановлено значення NO. Якщо рядок стану непрозорий, представлення даних не буде розширено, щоб включити рядок стану, навіть якщо ви розширите свій погляд, щоб охопити його ( edgesForExtendedLayoutдо UIRectEdgeAll).

Якщо встановити значення YES, це дозволить перегляду знову перейти під рядок стану.

Якщо щось не зрозуміло, напишіть коментар, і я відповім на нього.

Як iOS знає, що UIScrollView використовувати?

iOS захоплює перший підпогляд у представленні вашого ViewController, той, який знаходиться в індексі 0, і якщо це підклас, UIScrollViewтоді застосовує до нього пояснені властивості.

Звичайно, це означає, що UITableViewControllerпрацює за замовчуванням (оскільки UITableViewце перший погляд).


Нам потрібно встановити ці властивості лише в тому випадку, якщо ми показуємо панель навігації за замовчуванням, а не якщо її налаштована панель навігації, правда?
Hemang

1
Ні, якщо ви користуєтесь панеллю навігації iOS, але при власному дизайні вам потрібно буде використовувати ті самі властивості. Якщо ви просто створили панель навігації на нутрі, ці властивості не працюватимуть.
Антоніо МГ

Я не розумію, чому на всьому погляді виникає невеликий чорнуватий шар? Будь ласка, допоможіть? : /
aZtraL-EnForceR

24
Це пояснення набагато краще, ніж IOS 7 UI Transition Guide. Це має просто замінити путівник, який для мене не мав сенсу.
Сем

2
Я думаю, що ExtellLinkoutIncludesOpaqueBars за замовчуванням повинен бути ТАК замість НІ. Зміна кольорів перегляду (прозорість) не повинно впливати на макет.
Владимир Славік

15

Не впевнений, що ви використовуєте мовленнєві дошки, але якщо ви є, щоб змусити ваші контролери перегляду запуститись нижче рядка стану (і над нижньою панеллю):

Виберіть контролер перегляду в ІБ, в інспекторі атрибутів зніміть позначку "Розширити краї - Під верхніми смугами" та "Розширити краї - Під нижньою смугою".


ГАРАЗД. Тоді я думаю, що те, що запропонував Нандха, буде досягти того ж результату програмно. Якщо він не працює під viewDidLoad, його, можливо, потрібно буде перенести на viewDidLayoutSubviews.
Алі Бісл

Вказує, чи включає розширений макет непрозорі смуги. @property (неатомічне, присвоєння) BOOL extensionLayoutIncludesOpaqueBars Обговорення Значення за замовчуванням НІ.
Абдул Ясін

+1, ти дав мені підказку перевірити в «Радці». І я вирішив свою половину проблеми.
selva

10

Я використовую дошки та використовуючу вищезазначену пораду, однак я не був точно впевнений, як це реалізувати. Нижче наводиться короткий приклад, як швидко усунути проблему, помістивши рекомендоване рішення у ViewController.

import Foundation
import UIKit

// This ViewController is connected to a view on a storyboard that 
// has a scrolling sub view.
class TheViewController: UIViewController {

  // Prepares the view prior to loading.  Putting it in viewDidAppear didn't work.
  override func viewWillAppear(animated: Bool) {

    // this method is an extension of the UIViewController 
    // so using self works as you might expect.
    self.automaticallyAdjustsScrollViewInsets = false

    // Default is "true" so this sets it to false tells it to use 
    // the storyboard as you have it placed
    // and not how it thinks it should place it.
  }

}

Моя проблема: Автоматичне налаштування встановлено на значення true за замовчуванням, викликаючи різницю між дизайном та симулятором Автоматичне налаштування встановлено на значення true за замовчуванням, викликаючи різницю між дизайном та симулятором

Вирішено: код застосовано вище, вимкнувши автоматичне регулювання. Код, застосований вище, вимикаючи автоматичне регулювання.


5
якщо ввімкнути функцію автоматичноAdjustsScrollViewInsets як ТАК, вам слід встановити верхнє обмеження для нагляду, а не topGuideLayout.
xmkevinchen

5

Я вирішив цю проблему, додавши цей рядок, але моя проблема була пов'язана з a UIView, ніUIScrollView

self.navigationController.navigationBar.translucent = NO;

2

Тільки майте на увазі, що automaticallyAdjustsScrollViewInsets властивість працює лише в тому випадку, якщо вигляд прокрутки (подання таблиці, подання колекції, ...) є будь-яким

  • Вид ВК, або
  • Перший підвід цього погляду

Інші припускають, що це працює, навіть якщо це перший підвід, але в ієрархії перегляду є інші види прокрутки.

EDIT (розширення DIY)

Якщо ви хочете подібної поведінки, навіть якщо ви не можете виконати ці умови (наприклад, у вас фонове зображення під вікном прокрутки), ви можете налаштувати вставки виду прокрутки вручну. Але, будь ласка, не встановлюйте його на постійне значення, як 44, 64 або навіть 20, як багато з них пропонують навколо SO. Ви не можете знати розмір ніколи. Тут може бути повідомлення про висоту / gps / аудіо, панель навігації не завжди повинна бути 44 балів тощо.

Я думаю, що найкращим рішенням є використання layoutGuide lengthу didLayoutSubviews:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    scrollView.contentInset = UIEdgeInsets(top: topLayoutGuide.length, left: 0, bottom: 0, right: 0)
    scrollView.scrollIndicatorInsets = scrollView.contentInset
}

Ви можете використовувати нижній LayoutGuide таким же чином.


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