Измерение подвида
Запрашивайте размеры подвидов во время компоновки.
«Измерение подвида» — бесплатный урок Swift Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Swift Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Swift Academy содержит 4 уроков всего.
Измерение определяет компоновку
Прежде чем размещать дочерние элементы, необходимо их измерить. Компоновка в SwiftUI — это согласование: родительский элемент предлагает размеры, дочерние элементы отвечают, а Вы согласуете результаты.
Запрос размера дочернего представления
Каждый прокси в Subviews отвечает на вызов sizeThatFits(_:) для заданного ProposedViewSize. Прокси возвращает размер, который занял бы дочерний элемент при таком предложении.
let size = subview.sizeThatFits(.unspecified)Три пробных предложения
Чтобы узнать гибкость дочернего элемента, проверьте его тремя способами: .zero показывает минимальный размер, .infinity — максимальный, а .unspecified — ideal-размер.
let minSize = subview.sizeThatFits(.zero)
let maxSize = subview.sizeThatFits(.infinity)
let ideal = subview.sizeThatFits(.unspecified)Предложение конкретной ширины
Для текста с переносом предложите конкретную ширину, оставив высоту равной nil. Дочерний элемент сообщит высоту, необходимую ему при такой ширине.
let proposal = ProposedViewSize(width: 200, height: nil)
let fit = subview.sizeThatFits(proposal)Приоритет макета
Каждое дочернее представление предоставляет значение priority (задаваемое с помощью .layoutPriority). Когда места мало, сначала выделяйте дочерним представлениям с более высоким приоритетом их идеальный размер.
for subview in subviews {
let p = subview.priority
// distribute space to higher priority first
}Чтение пользовательских значений
Дочерние представления могут хранить типизированные данные с помощью LayoutValueKey. Макет считывает значение subview[MyKey.self], чтобы управлять размещением, например задавать индивидуальное расстояние для элемента.
private struct RankKey: LayoutValueKey {
static let defaultValue: Int = 0
}
let rank = subviews[0][RankKey.self]Задание значения макета
Представление задаёт значение макета с помощью модификатора layoutValue(key:value:), позволяя дочерним представлениям передавать подсказки Вашему макету.
Text("Featured").layoutValue(key: RankKey.self, value: 10)Расстояние между дочерними представлениями
Дочерние представления предоставляют предпочтения spacing. Используйте subview.spacing.distance(to:along:), чтобы получить рекомендуемое расстояние между двумя соседними дочерними представлениями вдоль оси.
let gap = subviews[0].spacing.distance(
to: subviews[1].spacing, along: .horizontal)Суммирование размеров
Горизонтальный макет суммирует ширину дочерних представлений и выбирает максимальную высоту. Измерение всех дочерних представлений сначала позволяет вычислить размер контейнера до размещения элементов.
let sizes = subviews.map { $0.sizeThatFits(.unspecified) }
let totalWidth = sizes.reduce(0) { $0 + $1.width }
let maxHeight = sizes.map(\.height).max() ?? 0Повторное измерение при размещении
В placeSubviews необходимо повторно измерить представления (или использовать кэшированные размеры), чтобы позиции соответствовали заявленным размерам. Измерения — это дешёвые прокси-вызовы, а не настоящая отрисовка.
func placeSubviews(in bounds: CGRect, proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) {
for s in subviews {
let size = s.sizeThatFits(.unspecified)
// use size to position s
_ = size
}
}Соблюдение предложения родителя
Всегда соблюдайте полученное предложение. Если родитель предлагает фиксированную ширину, размещайте дочерние представления в её пределах; не допускайте незаметного выхода за границы, иначе макет будет обрезан.
let containerWidth = proposal.width ?? .infinityБыстрая проверка: измерение
Проверьте понимание измерения дочерних представлений.
Итоги: измерение дочерних представлений
Измерение — основа пользовательского макета. Исследуйте дочерние представления с помощью .zero, .infinity и .unspecified, чтобы определить минимальные, максимальные и идеальные размеры, предлагайте конкретную ширину содержимому с переносом и соблюдайте приоритет макета и предпочтения по расстоянию.
Пользовательские значения LayoutValueKey позволяют дочерним представлениям передавать подсказки. Выполняйте измерения согласованно в обоих методах протокола, чтобы заявленный размер и размещение всегда совпадали.
Часто задаваемые вопросы
Урок «Измерение подвида» бесплатный?
Да — полный текст урока «Измерение подвида» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Swift Academy, подпишись на CoddyKit PRO. Курс Swift Academy содержит 4 уроков всего.
Чему я научусь в уроке «Измерение подвида»?
Запрашивайте размеры подвидов во время компоновки. Ты практикуешь Swift Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Swift Academy?
Предыдущий опыт не требуется. Swift Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Измерение подвида»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Swift Academy?
Да. Каждый урок Swift Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Основы протокола Layout
- Измерение подвида
- Создание потоковой компоновки
- Кэш компоновки и производительность