У меня есть следующее расширение, которое я получил от этот вопрос SO несколько месяцев назад, и я хотел бы перевести это на NSLayoutAnchor (или более подробные API-интерфейсы макета) по той простой причине, что визуальный формат не поддерживает указание руководства по макету безопасной области.
Расширение по ссылке вот такое:
extension UIView {
/// Adds constraints to this `UIView` instances `superview` object to make sure this always has the same size as the superview.
/// Please note that this has no effect if its `superview` is `nil` – add this `UIView` instance as a subview before calling this.
func bindFrameToSuperviewBounds() {
guard let superview = self.superview else {
print("Error! `superview` was nil – call `addSubview(view: UIView)` before calling `bindFrameToSuperviewBounds()` to fix this.")
return
}
self.translatesAutoresizingMaskIntoConstraints = false
superview.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": self]))
superview.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": self]))
}
}
Моя иерархия представлений:
UINavigationController -> контроллер корневого представления: UIPageViewController -> Первая страница: UIViewController -> UIScrollView -> UIImageView
Когда я вызываю bindFrameToSuperviewBounds()
, результат следующий:
Что выглядит в основном хорошо. Проблема в том, что просмотр изображения находится под панелью навигации, чего я не хочу. Итак, чтобы исправить это, я попытался переписать bindFrameToSuperviewBounds()
следующим образом:
guard let superview = self.superview else {
fatalError("Attempting to bound to a non-existing superview.")
}
translatesAutoresizingMaskIntoConstraints = false
self.topAnchor.constraint(equalTo: superview.safeAreaLayoutGuide.topAnchor).isActive = true
self.leadingAnchor.constraint(equalTo: superview.safeAreaLayoutGuide.leadingAnchor).isActive = true
self.bottomAnchor.constraint(equalTo: superview.safeAreaLayoutGuide.bottomAnchor).isActive = true
self.trailingAnchor.constraint(equalTo: superview.safeAreaLayoutGuide.trailingAnchor).isActive = true
Результат тогда такой:
На этот раз он правильно не проходит под панелью навигации, но что ж... Вы можете видеть, что он растягивается, чего я не хочу.
Каков правильный способ перевести этот API визуального макета во что-то, что может учитывать руководство по макету безопасной зоны?
Для полноты ниже приведен код, который настраивает вид прокрутки и вид изображения:
override func viewDidLoad() {
super.viewDidLoad()
imageScrollView.addSubview(imageView)
imageScrollView.layoutIfNeeded()
imageView.bindFrameToSuperviewBounds()
view.addSubview(imageScrollView)
imageView.layoutIfNeeded()
imageScrollView.backgroundColor = .white
imageScrollView.bindFrameToSuperviewBounds()
imageScrollView.delegate = self
}