Как вы можете или можете создать и/или «настроить» свойство NSLayoutAnchor?

Допустим, у вас есть большое сложное пользовательское представление,

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 вниз, и вернуть привязку этого представления!)

Как? Является ли это возможным?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
65
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

На самом деле есть несколько способов сделать это, в зависимости от того, что именно вы пытаетесь сделать.


Допустим, единственный способ прикрепить что-либо к верхней части представления — это на самом деле 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) именно для того, чтобы вы могли делать подобные вещи без дополнительных затрат на использование невидимых «разделительных» представлений.

НЕВЕРОЯТНЫЙ ! Кроме того, выравниваниеRectInsets — невероятный совет.

Fattie 21.06.2024 20:50

Интересно,можете ли вы предоставить якорь размеров..высоту или ширину..Задам еще вопрос!

Fattie 22.06.2024 15:37

о, я вижу, что на самом деле у него есть все свои ограничения, если вы установили достаточно. замечательный

Fattie 22.06.2024 15:39

«Предполагая» См. комментарий в моем коде «и то же самое для трейлинга и дна»? Я пропустил эти две строчки, но вы можете написать их самостоятельно в качестве упражнения. Вы должны написать их; вы должны установить достаточные ограничения для руководства по макету при его создании. После этого, конечно, у него есть высота, ширина и все такое. Он позиционируется так же, как представление — но это не представление, а всего лишь расчетный «фрейм».

matt 22.06.2024 15:42

лол да, я понял, отличный ответ!!!! Оказывается, вы можете установить в руководстве по макету столько ограничений, сколько захотите; если вы просто хотите продать, скажите верх. (Нет ошибок: похоже, что решатель не действует до тех пор, пока ему не будет задано что-то неразрешимое.) Так здорово! Я привел «единственный» пример

Fattie 22.06.2024 18:34

Поле не является краем, поэтому оно не прикреплено к левому краю, как вы так грубо утверждаете; скорее, он прикреплен к левому полю, а это совсем другое. Прямоугольник выравнивания изменяет верхнюю, левую, нижнюю и правую привязки, но не влияет на поля, которые определяются направляющей полей макета.

matt 28.06.2024 17:21

Извините, в моем комментарии допущена критическая опечатка! Если прикрепить его к левому ЯКОРЮ... то... я был очень удивлён, увидев, что он вроде бы прикрепляет его к ОРИГИНАЛЬНОМУ левому краю, а не к "новому" левому краю! Мне придется изучить это и сделать демо!

Fattie 28.06.2024 18:47

Для тех, кто здесь гуглит, просто еще один пример из превосходного ответа, отмеченного галочкой на этой странице; здесь нужен только один гид

Продавец ...

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
}()

(*) Умный совет...

Анимация продаваемых вами руководств по макетам может стать мощным способом инкапсуляции материала.

Я полагаю, вы могли бы это сделать; вы можете закрепить только верхнюю часть руководства по макету, при условии, что верхняя часть руководства по макету является единственной привязкой руководства по макету, к которой вы прикрепляете. Но я не могу этого посоветовать; Собственный макет руководства по верстке совершенно неоднозначен, и это плохо.

matt 22.06.2024 20:46

Теперь, когда я вижу, что вы пытаетесь использовать это таким образом, я добавил к своему ответу еще один подход; Я поставил его на второе место в списке. Я подозреваю, что этот новый второй подход — именно тот, который вам действительно нужен.

matt 22.06.2024 20:57

еще одна замечательная техника!!! Раньше я использовал макетMarginsGuide. Очень удобно иметь полностью гибкие якоря, сколько вам нужно. (Что касается проблемы «неполных» руководств по макету: мне кажется более логичным (когда вы хотите продать только одно), обратите внимание (мой блок кода № 1 здесь), это только продажа NSLayoutYAxisAnchor, руководство недоступно (даже для этого класс!) Это руководство по компоновке «на самом деле является только» SSOT для рассматриваемого верхнего якоря; то есть, если бы «кто-то еще из команды» попытался использовать это руководство для получения высоты, левого угла и т. д., он был бы концептуально полностью ошибочен, и это (должен) разбиться.

Fattie 22.06.2024 23:13

вы, как всегда, снова спасли положение, великолепно! его руководства по компоновке теперь повсюду.

Fattie 22.06.2024 23:14

(в отношении «неполных» руководств по компоновке; при этом, если бы здесь случайно оказался пресловутый младший программист, я бы просто сказал ему: «Вы ничего здесь не видели, сделайте это полным прямоугольником», лол)

Fattie 22.06.2024 23:15

«это всего лишь продажа NSLayoutYAxisAnchor» Это отличный момент! Но я бы все же посоветовал воздержаться от незавершенности, даже под капотом.

matt 23.06.2024 00:17

Другие вопросы по теме

Неопределенное поведение ячеек UICollectionView
SwiftUI/UIKit — выделяйте кнопки и текст панели навигации
Как мне экспортировать радиальный градиент Figma в CAGradientLayer?
SwiftUI, как скрыть панель навигации «больше» на 5-й и 6-й вкладках в пользовательском представлении вкладок
UIActivityViewController отображается в неправильном положении на iPad, когда он представлен в виде всплывающего окна в SwiftUI
Есть ли какой-либо встроенный способ получить мантиссу и показатель степени (значения «научной нотации» или «электронной нотации») CGFloat в Swift?
Размещение представления в виде снизу в другом представлении не работает должным образом при использовании SwiftUI
Нет такого модуля «UIKit» для проекта SwiftUI
Можно ли добавить собственный переход к дочерним элементам TabView при изменении страницы?
Основное статическое свойство «текст», изолированное от актера, не может быть изменено из неизолированного контекста; это ошибка в Swift 6