safeAreaLayoutGuide - ландшафтный режим
Я установил safeAreaLayoutGuide следующим образом:
let guide = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
topControls.topAnchor.constraint(equalTo: guide.topAnchor, constant: 0)
])
это прекрасно работает Однако, когда я поворачиваю устройство в альбомный режим, строка состояния (батарея, сигнал и т. Д.) Отсутствует, и смещение от верхней части экрана равно нулю. Это правильно, на основе якоря. Тем не менее, это не выглядит хорошо. Как добавить смещение 20 для ландшафта при создании якорей? Я не хочу менять константу в зависимости от ориентации вручную.
1 ответ
Предполагая, что вы работаете на iPhone, это ожидаемое поведение и может быть изменено путем переопределения следующего:
override var prefersStatusBarHidden: Bool {
return false
}
Из описания этого метода UIViewController:
По умолчанию этот метод возвращает false с одним исключением. Для приложений, связанных с iOS 8 или новее, этот метод возвращает true, если контроллер представления находится в вертикально компактной среде.
Если вы переопределите это, вы получите строку состояния в альбомной ориентации, и руководство по безопасной области будет соответствующим образом адаптировано.
РЕДАКТИРОВАТЬ
Так что небольшое недоразумение с первоначальным требованием. Это не для того, чтобы показать строку состояния, но чтобы иметь пробел, как если бы была строка состояния.
Это нужно будет сделать вручную, так как вы не можете установить ограничения, которые применяются только в определенных классах ориентации / размера вручную.
Это базовый UIViewController, который будет делать то, что вы ищете:
class ViewController: UIViewController {
var testView: UIView!
var landscapeConstraint: NSLayoutConstraint!
var portraitConstraint: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.testView = UIView()
self.testView.backgroundColor = .green
self.view.addSubview(self.testView)
self.testView.translatesAutoresizingMaskIntoConstraints = false
let guide = view.safeAreaLayoutGuide
self.testView.leftAnchor.constraint(equalTo: guide.leftAnchor, constant: 0).isActive = true
self.testView.rightAnchor.constraint(equalTo: guide.rightAnchor, constant: 0).isActive = true
self.testView.bottomAnchor.constraint(equalTo: guide.bottomAnchor, constant: 0).isActive = true
self.portraitConstraint = self.testView.topAnchor.constraint(equalTo: guide.topAnchor, constant: 0)
self.landscapeConstraint = self.testView.topAnchor.constraint(equalTo: guide.topAnchor, constant: 20) // Hardcoded the size but this can be anything you want.
switch self.traitCollection.verticalSizeClass {
case .compact:
self.landscapeConstraint.isActive = true
case.regular:
self.portraitConstraint.isActive = true
default: // This shouldn't happen but let's assume regular (i.e. portrait)
self.portraitConstraint.isActive = true
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
super.willTransition(to: newCollection, with: coordinator)
switch newCollection.verticalSizeClass {
case .compact:
self.portraitConstraint.isActive = false
self.landscapeConstraint.isActive = true
case.regular:
self.landscapeConstraint.isActive = false
self.portraitConstraint.isActive = true
default: // This shouldn't happen but let's assume regular (i.e. portrait)
self.landscapeConstraint.isActive = false
self.portraitConstraint.isActive = true
}
}
}
По сути, вы устанавливаете фиксированные ограничения, то есть слева, справа и снизу, а затем устанавливаете ограничения для портрета и ландшафта (класс обычного и компактного вертикального размера), которые по умолчанию отключены. Затем вы решаете, какой из них активировать, основываясь на текущем классе ориентации / размера. Затем вы переопределяете:
willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator)
метод и поменяйте местами активное состояние двух ограничений на основе нового класса ориентации / размера.
Следует отметить, что сначала необходимо всегда деактивировать ограничения, а затем активировать их, чтобы избежать каких-либо жалоб на ограничения, которые не могут быть выполнены.