Ответ 1
Будучи предложителем Баунти... Я бы сказал, что большая часть моего замешательства возникла из-за неправильного понимания класса UILayoutGuide
. Это ключевой момент, но также очень простой.
Позвольте мне сначала представить проблему:
В старые времена, если вам нужно было ограничить эти круги следующим образом:
Затем вам нужно было создать чистые UIViews и добавить их в качестве ваших подпредставлений, а затем добавить к ним свои ограничения, как показано ниже:
Сегодня вам не нужно добавлять их в качестве своих подпредставлений. Вместо этого вы можете просто использовать
Руководства по макету
Чтобы создать руководство по макету, необходимо выполнить следующие действия:
- Создание нового руководства по макету.
- Добавьте руководство по макету в представление, вызвав метод views
addLayoutGuide(_:)
. - Определите положение и размер руководства по макету, используя Auto Layout. Вы можете использовать эти направляющие для определения пространства между элементами в макете. В следующем примере показаны направляющие макета, используемые для определения равного расстояния между сериями видов.
шаги:
let space1 = UILayoutGuide()
view.addLayoutGuide(space1)
let space2 = UILayoutGuide()
view.addLayoutGuide(space2)
space1.widthAnchor.constraintEqualToAnchor(space2.widthAnchor).active = true
saveButton.trailingAnchor.constraintEqualToAnchor(space1.leadingAnchor).active = true
cancelButton.leadingAnchor.constraintEqualToAnchor(space1.trailingAnchor).active = true
cancelButton.trailingAnchor.constraintEqualToAnchor(space2.leadingAnchor).active = true
clearButton.leadingAnchor.constraintEqualToAnchor(space2.trailingAnchor).active = true
Направляющие макетов также могут выступать в роли черного ящика, содержащего ряд других видов и элементов управления. Это позволяет вам инкапсулировать часть вашего представления, разбивая ваш макет на модульные блоки.
Три интересные заметки:
- Если вы используете "просмотр иерархии отладки", вы увидите больше экземпляров
UILayoutGuide
- Как и в UIView, экземпляр UILayoutGuide имеет все виды якорей
- Что касается того, почему не просто создать фиктивные UIViews и пройти через создание UILayoutGuides: "Существует несколько затрат, связанных с добавлением фиктивных представлений в вашу иерархию представлений. Во-первых, это стоимость создания и поддержки самого представления. Во-вторых, фиктивное представление является полноправным членом иерархии представления, что означает, что он добавляет издержки к каждой задаче, которую выполняет иерархия. Хуже всего то, что невидимое фиктивное представление может перехватывать сообщения, предназначенные для других представлений, вызывая проблемы, которые очень трудно найти ".
Для получения дополнительной информации см. документацию.
topLayoutGuide
против safeAreaLayoutGuide
topLayoutGuide (устарело)
Не рекомендуется, но для целей обучения: у UIViewController
есть 2 пустышки. 1 свойство вверху с именем topLayoutGuide
и другое свойство внизу с именем bottomLayoutGuide
. Сам ViewController не имеет направляющих для левой/передней или правой/задней сторон. Оба они являются экземпляром UILayoutGuide
если ограничен view.topAnchor, т.е.:
tableView.topAnchor.constraint(equalTo: view.topAnchor)
tableView не начинается с нижней части панели навигации. Обратите внимание на оранжевый цвет за панелью навигации...
Однако, если вы ограничили его topLayoutGuide.bottomAnchor
, т.е.
tableView.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor)
затем tableView начинается с нижней части панели навигации
И в зависимости от вашего макета вы можете захотеть, чтобы ваш контент был размытым под панелью навигации.
И идея заключалась в том, что вы будете отображать ваш контент от края до края. А также это перекрыло бы бары, чтобы вы могли получить эти красивые красочные размывает контент через решетку
Подробнее см. этот момент из WWDC и этот вопрос здесь. Я не думаю, что решения точно связаны, только изображение в вопросе.
safeAreaLayoutGuide
с iOS11
Apple устарела
topLayoutGuide
&bottomLayoutGuide
. Так вместо двух пустышек теперь у вас есть пустышка с именемsafeAreaLayoutGuide
в экземпляре UIView. У UIViewController больше нет этого... Визуальное сравнение скопировано из useyourloaf:
примечание: если вы используете раскадровки, то выравнивание ваших представлений с topLayoutGuide или top из safeAreaLayoutGuide будет отображать то же самое. Если вы не используете раскадровки (делайте это программно), вам придется танцевать между iOS11 и LessThaniOS11 и иметь 2 разные версии кода
Для получения дополнительной информации о safeAreaLayoutGuide
я настоятельно рекомендую установить статью Apple на: Позиционирование контента относительно безопасной зоны
ПРИМЕЧАНИЕ. safeAreaLayoutGuide
- это свойство UIView. topLayoutGuide
является свойством UIViewController.
layoutMarginsGuide
UIView
имеет только 1 пустышку. Свойство называетсяlayoutMarginsGuide
. Но в отличие отUIViewController
он не сидит сверху или снизу. Он просто расположен в центре с 8-точечным заполнением/вставкой (со всех четырех сторон) вUIView
.Итак, где это полезно?:Вы бы использовали это, если вы не делаете хотите, чтобы ваш textView был ограничен краями экземпляра UIView. Это улучшит опыт чтения. Или вместо того, чтобы ограничить кнопку ведущим якорем ее суперпредставления и сделать его уродливым, вы добавляете 8 ячеек к якору... то есть ограничиваете кнопку в ведущем якоре и затем добавляете 8 постоянных точек.Выделенный текст, на самом деле, вы бы использовалиreadableContentGuide
,layoutMarginsGuide
полезно, если вы не хотите, чтобы ваша кнопка или метка были прикреплены к краю суперпредставленияsomeButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 8)
Но подождите, есть более простой способ. Просто используйте рекомендованную Apple маржу, т.е. используйте:
someButton.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor)
Также см. пример, приведенный в документация. Хороший учебник Raywenderlich можно найти здесь
readableContentGuide
Немного отличается от
layoutMarginGuide
. Оба являются свойствами UIView. Иногда они идентичны, иногда нет. Это цель:Это руководство по макету определяет область, которая может быть легко прочитана без заставляя пользователей двигать головой, чтобы отслеживать линии
Подробнее см. этот момент из WWDC: создание адаптивного макета и это замечательное руководство по использованию youyloloaf.
На iPhone 7 Plus в портретной ориентации читаемые руководства по содержанию одинаковы как ориентиры полей зрения, но в ландшафте есть больше белого пространство по обе стороны от текстового представления. На iPad в альбомной ориентации пробел значительно увеличен.
Размер поля зависит от динамического типа системы. Чем больше шрифт, тем шире будет руководство.
From RayWenderlich
На изображении ниже голубой привязан к layoutMarginGuide
, но зеленый привязан к readableContentGuide
:
UIEdgeInsets
Если вы хотите изменить layoutMarginsGuide
, то есть изменить желаемое поле с 8 до 16 баллов, вы должны изменить значение layoutMargins
, и якоря layoutMarginsGuide
будут автоматически обновлены.
UIEdgeInsets
это просто тип вашего layoutMargins
. layoutMargins
- это имя свойства класса UIView
someview.layoutMargins = UIEdgeInsets(top: 50, left: 50, bottom: 50, right: 50)
Единственное место, где я нашел этот код ☝️, чтобы он действовал, находится внутри viewDidLayoutSubviews
. Подробнее см. здесь
Anchors
Они основополагающие, но ничего особенного. Они являются самым дальним краем любого UIView/UILayoutGuide. И экземпляры UIView и UILayoutGuide имеют это. ВСЕ, которое вы ограничиваете, в конечном итоге ограничивается использованием якорей, это просто вопрос того, к каким объектам якоря вы привязываете. Это может быть якорь safeAreaLayoutGuide
, это может быть якорь layoutMarginGuide
, это может быть якорь topLayoutGuide
, это может быть якорь view
. (хотя вы также можете просто привязать свой heightAnchor к 50, так что в этом случае другого якоря не будет)
Великолепное визуальное сравнение между layoutMarginsGuide
и Anchors
можно найти из этого ответа. Это сделано с использованием раскадровок, чтобы облегчить понимание.
contentInsets
Хотя важно понимать, это совершенно другое обсуждение и не имеет ничего общего с другими. Это специфично для UIScrollViews. Подробнее читайте в этой замечательной статье
Заключение
Чтобы быть в безопасности и быть уверенным, что все внутри вашего зрения, используйте safeAreaLayoutGuide
. Если вы хотите использовать предоставленные системой поля, чтобы иметь лучшее расположение видов или иметь некоторые отступы, используйте layoutMarginGuide
, если вы хотите сделать вещи более читабельными readableContentGuide
.
Размер readableContentGuide
всегда меньше или равен layoutMarginGuide
.
Размер layoutMarginGuide
всегда меньше или равен safeAreaLayoutGuide
layoutMargins
очень похож на заполнение CSS. safeAreaLayoutGuide
похож на CSS поля. Я не знаю, есть ли какой-нибудь CSS-эквивалент для readableContentGuide
Приложение: ContentInset против contentOffset
Они предназначены для scrollViews и в некоторой степени не связаны с остальной частью ответа. Что касается того, что contentInset
& contentOffset
, смотрите этот момент из WWDC 2018: UIKit: приложения для любого размера и формы
. Видео очень простое. также см. ответ Karthik ниже. При этом важно, чтобы вы полностью понимали, как работает scrollView, и понимали, что такое contentSize
, иначе это будет сложно. Подробнее о contentSize
и scrollView см. ответ Vacawama здесь