Допустим, у вас есть большое сложное пользовательское представление,
lazy var pinkThing: ..
lazy var greenThing: ..
И ты хочешь
///For upstream views to use as they wish
var pinkCenterY: NSLayoutYAxisAnchor {
return pinkThing.centerYAnchor
}
и это нормально. Вы также можете (бессмысленно)
///For programmers who prefer to type .example than .topAnchor
var example: NSLayoutYAxisAnchor {
return topAnchor
}
Допустим, вы хотите вернуть привязку, то есть 42 пикселя от верха этого представления. Так это что-то вроде..
///For upstream views to know where the gauges area is at
var dialsSafeArea: NSLayoutYAxisAnchor {
return something something 42 something
}
также было бы полезно узнать, как «модифицировать» якоря, поэтому
///For upstream views to know where the gauges area is
var dialsSafeArea: NSLayoutYAxisAnchor {
return topAnchor something something 3 something
or say
return pinkThing.topAnchor something something 3 something
}
Возможно, я упускаю что-то очевидное, но я просто не смог этого понять.
(Обходной путь заключается в том, что вы можете создать невидимое представление, 42 вниз, и вернуть привязку этого представления!)
Как? Является ли это возможным?
На самом деле есть несколько способов сделать это, в зависимости от того, что именно вы пытаетесь сделать.
Допустим, единственный способ прикрепить что-либо к верхней части представления — это на самом деле 42 пикселя вниз от верхней части представления. Затем вы можете переопределить вставки прямоугольника выравнивания этого представления:
override var alignmentRectInsets: UIEdgeInsets {
.init(top: 42, left: 0, bottom: 0, right: 0)
}
В результате мы фактически переместили положение этого вида topAnchor
, и все, что прикрепляется к этому виду topAnchor
, будет измеряться от точки на 42 точки вниз от вершины физического вида.
Плюс этого подхода в том, что он автоматический. Никакие другие взгляды не должны знать об этом; вы просто прикрепляете к представлению topAnchor
и происходит то, что нужно. Это очень полезно, например, когда вид содержит вложенный рисунок и вам нужно прикрепить его к краю рисунка, а не к самому виду.
Другой подход — установить верхнюю часть полей макета вашего представления. У каждого представления есть поля, но в наши дни они используются очень мало; это может быть хорошим применением. Просто скажите
myView.layoutMargins.top = 42
Теперь, если вы хотите закрепить эту вещь на 42 пункта ниже верхней части myView, закрепите ее на myView.layoutMarginsGuide.topAnchor
.
(Я подозреваю, что это именно тот подход, который вам действительно нужен.)
Еще один подход, который требует немного больше работы, заключается в том, чтобы представление предоставило руководство по индивидуальному макету. (Я говорю «пользовательский», потому что layoutMarginsGuide
уже является встроенным руководством по макету.) Вызовите addLayoutGuide
в представлении, чтобы дать ему руководство по макету, присвойте руководству по макету идентификатор, чтобы вы могли найти его позже, а затем используйте ограничения между руководство по макету и представление владельца для размещения руководства по макету:
let guide = UILayoutGuide()
guide.identifier = "myCoolGuide"
myView.addLayoutGuide(guide)
guide.topAnchor.constraint(equalTo: myView.topAnchor, constant: 42).isActive = true
guide.leadingAnchor.constraint(equalTo: myView.leadingAnchor).isActive = true
// and so too for trailing and bottom
Тогда другое представление можно прикрепить к верхней привязке руководства по макету myView, а не к верхней привязке самого myView. Написание кода для получения ссылки на руководство по макету оставлено в качестве упражнения для читателя.
Обратите внимание, что это не то же самое, что «жалкое» невидимое представление, упомянутое в вашем вопросе, поскольку UILayoutGuide не является представлением. Это просто своего рода невидимый пространственный «рамок». Действительно, UILayoutGuide был изобретен (Apple) именно для того, чтобы вы могли делать подобные вещи без дополнительных затрат на использование невидимых «разделительных» представлений.
Интересно,можете ли вы предоставить якорь размеров..высоту или ширину..Задам еще вопрос!
о, я вижу, что на самом деле у него есть все свои ограничения, если вы установили достаточно. замечательный
«Предполагая» См. комментарий в моем коде «и то же самое для трейлинга и дна»? Я пропустил эти две строчки, но вы можете написать их самостоятельно в качестве упражнения. Вы должны написать их; вы должны установить достаточные ограничения для руководства по макету при его создании. После этого, конечно, у него есть высота, ширина и все такое. Он позиционируется так же, как представление — но это не представление, а всего лишь расчетный «фрейм».
лол да, я понял, отличный ответ!!!! Оказывается, вы можете установить в руководстве по макету столько ограничений, сколько захотите; если вы просто хотите продать, скажите верх. (Нет ошибок: похоже, что решатель не действует до тех пор, пока ему не будет задано что-то неразрешимое.) Так здорово! Я привел «единственный» пример
Поле не является краем, поэтому оно не прикреплено к левому краю, как вы так грубо утверждаете; скорее, он прикреплен к левому полю, а это совсем другое. Прямоугольник выравнивания изменяет верхнюю, левую, нижнюю и правую привязки, но не влияет на поля, которые определяются направляющей полей макета.
Извините, в моем комментарии допущена критическая опечатка! Если прикрепить его к левому ЯКОРЮ... то... я был очень удивлён, увидев, что он вроде бы прикрепляет его к ОРИГИНАЛЬНОМУ левому краю, а не к "новому" левому краю! Мне придется изучить это и сделать демо!
Для тех, кто здесь гуглит, просто еще один пример из превосходного ответа, отмеченного галочкой на этой странице; здесь нужен только один гид
Продавец ...
lazy var someTopAnchor: NSLayoutYAxisAnchor = {
let g = UILayoutGuide()
addLayoutGuide(g)
g.topAnchor.constraint(equalTo: topAnchor, constant: 42).isActive = true
print("added/returned a layout anchor")
return g.topAnchor
}()
вверх по течению...
lazy var red: UIView = {
let v = UIView.Typical
v.backgroundColor = .red
view.addSubview(v)
NSLayoutConstraint.activate([
v.heightAnchor.constraint(equalToConstant: 100),
v.widthAnchor.constraint(equalToConstant: 100),
v.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 100),
v.topAnchor.constraint(equalTo: mapView.someTopAnchor)
])
return v
}()
реальный пример использования
///Use this to be above the "fine print" (Maps logo, 'legal' link)
///which UIKit adds to a map view.
lazy var finePrintSafaAreaBottom: NSLayoutYAxisAnchor = {
let g = UILayoutGuide()
addLayoutGuide(g)
let bestGuessFinePrintView = {
for v in subviews {
if "MKAttributionLabel" .. etc etc
}()
let comfortable = bestGuessFinePrintView.minY - 8
g.topAnchor.constraint(equalTo: topAnchor,
constant: comfortable).isActive = true
return g.topAnchor
}()
Анимация продаваемых вами руководств по макетам может стать мощным способом инкапсуляции материала.
Я полагаю, вы могли бы это сделать; вы можете закрепить только верхнюю часть руководства по макету, при условии, что верхняя часть руководства по макету является единственной привязкой руководства по макету, к которой вы прикрепляете. Но я не могу этого посоветовать; Собственный макет руководства по верстке совершенно неоднозначен, и это плохо.
Теперь, когда я вижу, что вы пытаетесь использовать это таким образом, я добавил к своему ответу еще один подход; Я поставил его на второе место в списке. Я подозреваю, что этот новый второй подход — именно тот, который вам действительно нужен.
еще одна замечательная техника!!! Раньше я использовал макетMarginsGuide. Очень удобно иметь полностью гибкие якоря, сколько вам нужно. (Что касается проблемы «неполных» руководств по макету: мне кажется более логичным (когда вы хотите продать только одно), обратите внимание (мой блок кода № 1 здесь), это только продажа NSLayoutYAxisAnchor, руководство недоступно (даже для этого класс!) Это руководство по компоновке «на самом деле является только» SSOT для рассматриваемого верхнего якоря; то есть, если бы «кто-то еще из команды» попытался использовать это руководство для получения высоты, левого угла и т. д., он был бы концептуально полностью ошибочен, и это (должен) разбиться.
вы, как всегда, снова спасли положение, великолепно! его руководства по компоновке теперь повсюду.
(в отношении «неполных» руководств по компоновке; при этом, если бы здесь случайно оказался пресловутый младший программист, я бы просто сказал ему: «Вы ничего здесь не видели, сделайте это полным прямоугольником», лол)
«это всего лишь продажа NSLayoutYAxisAnchor» Это отличный момент! Но я бы все же посоветовал воздержаться от незавершенности, даже под капотом.
НЕВЕРОЯТНЫЙ ! Кроме того, выравниваниеRectInsets — невероятный совет.