ai-benchmark/tests/summarization/nuancesprog.ru_p_30828.txt
second_constantine 25e0a2a96a Remove "Лог файл" column from report
Remove the "Лог файл" (Log file) column from the report generation as it's no longer needed. This simplifies the report structure and removes unused functionality.
2026-01-26 22:40:44 +03:00

66 lines
7.6 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

При создании представлений SwiftUI, которые должны адаптироваться к размерам контейнера, многие разработчики обращаются к GeometryReader. Это стандартное решение, но оно имеет свои издержки: влияя на иерархию представлений, может усложнить логику макета. В этой статье я покажу, как создать правильный модификатор с помощью onGeometryChange и contentMargins — двух мощных API iOS 17+, которые позволяют отслеживать изменения геометрии без обертывания представлений в GeometryReader. Примечание: onGeometryChange вышел с iOS 17 SDK, но был портирован на iOS 16. Проблема: скрытые затраты GeometryReader Допустим, вам надо центрировать контент по горизонтали с ограничением максимальной ширины. Это распространенная задача для макетов iPad или дизайнов для широких экранов. Традиционный подход выглядит примерно так: var body: some View {
GeometryReader { geometry in
ScrollView {
LazyVStack {
// Контент
}
.frame(maxWidth: 768)
}
.contentMargins(
.horizontal,
max(0, (geometry.size.width - 768) / 2),
for: .scrollContent
)
}
} Это работает, но GeometryReader имеет несколько недостатков: влияет на компоновку: занимает все доступное пространство, что может нарушить иерархию представлений; приводит к многословности: требуется оборачивать всю структуру представлений; не подлежит переиспользованию: этот паттерн приходится повторять во множестве представлений. Решение: правильный ViewModifier Вместо оборачивания представлений в GeometryReader, можно создать переиспользуемый модификатор, который применяет onGeometryChange для отслеживания изменений размера без влияния на компоновку. Вот как это сделать: import SwiftUI
struct MaxWidthContentMargins: ViewModifier {
@State private var containerWidth: CGFloat = 0
func body(content: Content) -> some View {
content
.onGeometryChange(
for: CGFloat.self,
of: { geometry in
geometry.size.width
}
) { width in
containerWidth = width
}
.contentMargins(
.horizontal,
max(0, (containerWidth - .editorMaxColumnWidth) / 2),
for: .scrollContent
)
}
}
extension View {
func maxWidthContentMargins() -> some View {
modifier(MaxWidthContentMargins())
}
}
Как это работает 1. onGeometryChange: отслеживание без влияния Модификатор onGeometryChange позволяет отслеживать изменения геометрии без обертывания представления в GeometryReader. Он имеет три параметра: for: тип отслеживаемого значения (в данном случае CGFloat для ширины); of: замыкание, которое извлекает значение из GeometryProxy; action: замыкание, которое выполняется при изменении геометрии. .onGeometryChange(
for: CGFloat.self,
of: { geometry in
geometry.size.width
}
) { width in
containerWidth = width
} Вот ключевое отличие: onGeometryChange отслеживает геометрию, не влияя на иерархию представлений. Ваши представления остаются чистыми и неизмененными. 2. contentMargins: точное позиционирование контента Модификатор contentMargins позволяет регулировать отступы вокруг прокручиваемого контента, не затрагивая индикаторы прокрутки. Это идеально подходит для центрирования контента при сохранении индикаторов прокрутки у краев экрана. При этом чистое пространство, которое стало отступами, остается прокручиваемым и интерактивным. .contentMargins(
.horizontal,
max(0, (containerWidth - .editorMaxColumnWidth) / 2),
for: .scrollContent
) Данное вычисление max(0, (containerWidth — .editorMaxColumnWidth) / 2) обеспечивает: на широких экранах: центрирование Content с равными отступами с обеих сторон; на узких экранах: отсутствие дополнительных отступов (функция max(0, …) предотвращает появление отрицательных значений) Применение модификатора Теперь применение модификатора становится предельно простым: struct LibraryView: View {
var body: some View {
ScrollView {
LazyVStack {
// Контент
}
.frame(maxWidth: .editorMaxColumnWidth)
}
.maxWidthContentMargins()
}
} Никаких оберток GeometryReader. Никаких повторяющихся геометрических вычислений. Всего лишь чистый, декларативный модификатор. Читайте также: Как вернуть контроль над состоянием данных с RemoteResult Apple убивает Swift 7 лучших ресурсов для iOS-разработчиков в 2025 году Читайте нас в Telegram, VK и Дзен Перевод статьи Thomas Ricouard: Beyond GeometryReader: Building Better SwiftUI Modifiers with onGeometryChange
==============
В статье рассматривается альтернатива использованию GeometryReader для адаптации представлений SwiftUI к размерам контейнера. Предлагается использование модификатора `MaxWidthContentMargins` на основе API `onGeometryChange` и `contentMargins`. Модификатор `onGeometryChange` позволяет отслеживать изменения геометрии без влияния на иерархию представлений, что упрощает компоновку. Модификатор `contentMargins` обеспечивает точное позиционирование контента, сохраняя интерактивность индикаторов прокрутки. Использование модификатора позволяет избежать проблем, связанных с GeometryReader, таких как влияние на компоновку и многословность, обеспечивая переиспользуемый и декларативный подход.