0Pricing
Swift Academy · Урок

Измерение подвида

Запрашивайте размеры подвидов во время компоновки.

«Измерение подвида» — бесплатный урок 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 — локальная установка не требуется.

Все уроки этого курса

  1. Основы протокола Layout
  2. Измерение подвида
  3. Создание потоковой компоновки
  4. Кэш компоновки и производительность
← Назад к Swift Academy