✨ Организация представлений SwiftUI с помощью ToolbarContent и @ToolbarContentBuilder
По мере роста проектов SwiftUI одна из частых проблем — управление сложными иерархиями представлений. Даже простой экран может быстро превратиться в десятки вложенных модификаторов. После снятия лимита в 10 вложенных представлений стало проще писать глубоко вложенные body, но код стал труднее читать и сопровождать.
🔹 Разбираем крупные реализации body
Когда body растягивается на десятки строк, страдает читаемость. Лучше разбивать большие представления SwiftUI на мелкие подпредставления или выделять повторно используемые части в вычисляемые свойства или функции. Это сохраняет лаконичность и упрощает понимание, тестирование и повторное использование.
Тот же принцип применим к невизуальным элементам, например панелям инструментов, которые быстро разрастаются при добавлении множества кнопок и пунктов меню.
🔹 Проблема с панелями инструментов
Модификатор .toolbar позволяет создавать кнопки, меню и элементы управления, адаптируемые под разные платформы. Но если элементов становится много, код внутри .toolbar { ... } быстро теряет читаемость.
Перенести логику в вычисляемое свойство нельзя — .toolbar ожидает содержимое, соответствующее ToolbarContent.
🔹 ToolbarContent и @ToolbarContentBuilder
SwiftUI решает это с помощью:
• ToolbarContent — протокола для элементов панели инструментов;
• @ToolbarContentBuilder — билдера, создающего набор элементов панели.
Объединив их, можно вынести содержимое панели инструментов в отдельный блок, сделав body чище и понятнее.
Пример
struct DemoView: View {
@State private var message = "Hello, world!"
var body: some View {
NavigationStack {
Text(message)
.font(.title2)
.padding()
.navigationTitle("Home")
.toolbar { toolbarContent }
}
}
@ToolbarContentBuilder
private var toolbarContent: some ToolbarContent {
ToolbarItem(placement: .navigationBarLeading) {
Button { message = "Left tapped" } label: {
Label("Left", systemImage: "line.3.horizontal")
}
}
ToolbarItem(placement: .navigationBarTrailing) {
Button { message = "Right tapped" } label: {
Label("Right", systemImage: "star")
}
}
}
}
🔹 Заключение
Использование @ToolbarContentBuilder для отделения содержимого панели инструментов от основного окна имеет ряд преимуществ:
• Улучшена читаемость: Ваш body текст по-прежнему сосредоточен на вёрстке, а логика панели инструментов реализована в другом месте.
• Лучшая организация: Группировка элементов панели инструментов в отдельном блоке позволяет с первого взгляда оценить их структуру и расположение.
• Масштабируемость: Когда на панели инструментов появляется несколько кнопок, меню или условная логика, поддерживать её в рабочем состоянии становится намного проще.
🐸 Библиотека мобильного разработчика
#PixelPerfect #MiddlePath #Swift
По мере роста проектов SwiftUI одна из частых проблем — управление сложными иерархиями представлений. Даже простой экран может быстро превратиться в десятки вложенных модификаторов. После снятия лимита в 10 вложенных представлений стало проще писать глубоко вложенные body, но код стал труднее читать и сопровождать.
🔹 Разбираем крупные реализации body
Когда body растягивается на десятки строк, страдает читаемость. Лучше разбивать большие представления SwiftUI на мелкие подпредставления или выделять повторно используемые части в вычисляемые свойства или функции. Это сохраняет лаконичность и упрощает понимание, тестирование и повторное использование.
Тот же принцип применим к невизуальным элементам, например панелям инструментов, которые быстро разрастаются при добавлении множества кнопок и пунктов меню.
🔹 Проблема с панелями инструментов
Модификатор .toolbar позволяет создавать кнопки, меню и элементы управления, адаптируемые под разные платформы. Но если элементов становится много, код внутри .toolbar { ... } быстро теряет читаемость.
Перенести логику в вычисляемое свойство нельзя — .toolbar ожидает содержимое, соответствующее ToolbarContent.
🔹 ToolbarContent и @ToolbarContentBuilder
SwiftUI решает это с помощью:
• ToolbarContent — протокола для элементов панели инструментов;
• @ToolbarContentBuilder — билдера, создающего набор элементов панели.
Объединив их, можно вынести содержимое панели инструментов в отдельный блок, сделав body чище и понятнее.
Пример
struct DemoView: View {
@State private var message = "Hello, world!"
var body: some View {
NavigationStack {
Text(message)
.font(.title2)
.padding()
.navigationTitle("Home")
.toolbar { toolbarContent }
}
}
@ToolbarContentBuilder
private var toolbarContent: some ToolbarContent {
ToolbarItem(placement: .navigationBarLeading) {
Button { message = "Left tapped" } label: {
Label("Left", systemImage: "line.3.horizontal")
}
}
ToolbarItem(placement: .navigationBarTrailing) {
Button { message = "Right tapped" } label: {
Label("Right", systemImage: "star")
}
}
}
}
🔹 Заключение
Использование @ToolbarContentBuilder для отделения содержимого панели инструментов от основного окна имеет ряд преимуществ:
• Улучшена читаемость: Ваш body текст по-прежнему сосредоточен на вёрстке, а логика панели инструментов реализована в другом месте.
• Лучшая организация: Группировка элементов панели инструментов в отдельном блоке позволяет с первого взгляда оценить их структуру и расположение.
• Масштабируемость: Когда на панели инструментов появляется несколько кнопок, меню или условная логика, поддерживать её в рабочем состоянии становится намного проще.
🐸 Библиотека мобильного разработчика
#PixelPerfect #MiddlePath #Swift