На новом iPhone X, что было бы наиболее правильным способом получить верхнюю и нижнюю высоту для небезопасных областей?
ios
iphone-x
safearealayoutguide
Tulleb
источник
источник
keyWindow
было всегда,nil
поэтому я изменил егоwindows[0]
и удалил?
из необязательной цепочки, тогда это сработало.Чтобы получить высоту между направляющими макета, вы просто делаете
Итак
full frame height = 812.0
,safe area height = 734.0
Ниже приведен пример, где зеленый вид имеет рамку
guide.layoutFrame
источник
UIApplication.sharedApplication.keyWindow.safeAreaLayoutGuide.layoutFrame
, который имеет безопасную рамку.Свифт 4, 5
Прикрепить представление к привязке безопасной области с помощью ограничений можно в любом месте жизненного цикла контроллера представления, поскольку они ставятся в очередь API и обрабатываются после загрузки представления в память. Однако получение значений безопасной области требует ожидания ближе к концу жизненного цикла контроллера представления, например
viewDidLayoutSubviews()
.Это подключается к любому контроллеру представления:
Я предпочитаю этот метод, чтобы убрать его из окна (когда это возможно), потому что именно так был разработан API и, что более важно, значения обновляются во время всех изменений представления, например, изменений ориентации устройства.
Однако некоторые пользовательские представленные контроллеры представления не могут использовать вышеупомянутый метод (я подозреваю, потому что они находятся в переходных представлениях контейнера). В таких случаях вы можете получить значения из корневого контроллера представления, который всегда будет доступен в любом месте жизненного цикла текущего контроллера представления.
источник
viewDidLayoutSubviews
(которое можно вызывать несколько раз), вот решение, которое будет работать даже вviewDidLoad
: stackoverflow.com/a/53864017/7767664Ни один из других ответов здесь не работал для меня, но это сработало.
источник
Все ответы здесь полезны, спасибо всем, кто предложил помощь.
Однако, поскольку я вижу, что тема безопасной области немного запутана, что не будет хорошо документировано.
Поэтому я кратко изложу это здесь, чтобы облегчить понимание
safeAreaInsets
,safeAreaLayoutGuide
иLayoutGuide
.В прошивке 7, Apple представила
topLayoutGuide
иbottomLayoutGuide
свойство вUIViewController
, они позволили создать ограничения , чтобы сохранить свое содержание от быть скрыто UIKit барами , как статус, навигация или панель вкладок можно было с этими направляющими компоновками , чтобы указать ограничения на содержание, избегая его быть скрытыми верхними или нижними элементами навигации (панели UIKit, строка состояния, панель навигации или панель вкладок…).Например, если вы хотите, чтобы tableView начинался с верхнего экрана, вы сделали что-то вроде этого:
В iOS 11 Apple устарела эти свойства, заменив их одним руководством по макету безопасной области
Безопасная зона по Apple
Ниже выделена безопасная зона в iPhone 8 и iPhone X-серии:
safeAreaLayoutGuide
Является свойствомUIView
Чтобы получить высоту
safeAreaLayoutGuide
:Это вернет высоту стрелки на вашей картинке.
Теперь, как насчет того, чтобы получить высоту «надреза» и нижней высоты индикатора домашнего экрана?
Здесь мы будем использовать
safeAreaInsets
Ниже будет показана небезопасная область и расстояние от краев на iPhone 8 и одной из iPhone X-Series.
Теперь, если добавлена панель навигации
Итак, как получить небезопасную высоту зоны? мы будем использовать
safeAreaInset
Вот к решениям, однако они отличаются в важной вещи,
Первый:
Это вернет EdgeInsets, теперь вы можете получить доступ к верхней и нижней части, чтобы знать вставки,
Второй:
В первом случае вы выбираете вставки вида, поэтому, если там есть панель навигации, она будет рассмотрена, однако во втором случае вы получаете доступ к safeAreaInsets окна, поэтому панель навигации не будет рассматриваться.
источник
В iOS 11 есть метод, который сообщает, когда изменилось safeArea.
источник
Swift 5, Xcode 11.4
Это даст предупреждение об устаревании. 'keyWindow' устарело в iOS 13.0: его не следует использовать для приложений, которые поддерживают несколько сцен, поскольку оно возвращает ключевое окно для всех связанных сцен 'из-за связанных сцен. Я использую этот способ.
источник
Я работаю с фреймворками CocoaPods и в случае, если
UIApplication.shared
он недоступен, я используюsafeAreaInsets
в представленииwindow
:источник
safeAreaLayoutGuide Когда представление отображается на экране, это руководство отражает часть представления, которая не покрыта панелями навигации, панелями вкладок, панелями инструментов и другими представлениями предков. (В tvOS безопасная область отражает область, не покрытую рамкой экрана.) Если вид в настоящее время не установлен в иерархии видов или еще не виден на экране, края направляющих макета равны краям вида.
Затем, чтобы получить высоту красной стрелки на скриншоте это:
источник
Objective-C У кого была проблема, когда keyWindow равно nil . Просто поместите код выше в viewDidAppear (не в viewDidLoad)
источник
источник
Расширение Swift 5
Это можно использовать как расширение и вызывать с помощью: UIApplication.topSafeAreaHeight
Расширение UIApplication является необязательным, может быть расширением UIView или любым другим, предпочтительным, или, возможно, даже лучше глобальной функцией.
источник
Более округленный подход
источник
Для тех из вас, кто переходит в ландшафтный режим, вы должны обязательно использовать viewSafeAreaInsetsDidChange после поворота, чтобы получить наиболее обновленные значения:
источник