PreviewProvider — протокол SwiftUI, який визначає точку входу для генерації попередніх переглядів у Xcode Canvas. Реалізація протоколу дозволяє розробнику побачити інтерфейс без запуску симулятора, прискорюючи ітерацію на етапі верстки. За даними Apple Developer Documentation (2026), PreviewProvider є обов’язковим для всіх SwiftUI View, якщо проект використовує Canvas — без нього Canvas не відображає інтерфейс користувача. Дізнайтеся більше в статті про SwiftUI.
Головне
PreviewProvider — протокол SwiftUI, який визначає контракт для створення вмісту попереднього перегляду в Xcode Canvas. Протокол містить одну обов’язкову властивість: previews типу some View. Будь-яке значення, повернуте previews, відображається в Canvas як інтерактивний попередній перегляд. PreviewProvider не вимагає успадкування — достатньо статичної реалізації в extension.
Архітектурно PreviewProvider не є частиною середовища виконання SwiftUI — це виключно інструмент розробки. Протокол позначений атрибутом @available(iOS 13.0, *) і не компілюється в релізну збірку, оскільки Xcode використовує умовну компіляцію для виключення коду попереднього перегляду з продакшну. Це означає, що PreviewProvider не впливає на розмір бінарного файлу та продуктивність застосунку.
Властивість previews — єдина вимога PreviewProvider. Вона має повертати будь-яку View: від простого Text до складної ієрархії з Group та ForEach. Xcode рендерить повернуту View у Canvas, застосовуючи системні налаштування (тему, розмір, шрифт).
import SwiftUI
struct GreetingView: View {
let name: String
var body: some View {
Text("Hello, \(name)!")
.padding()
}
}
// PreviewProvider — static implementation
struct GreetingView_Previews: PreviewProvider {
static var previews: some View {
GreetingView(name: "World")
}
}
Конвенція іменування: Apple рекомендує називати структуру попереднього перегляду як {ViewName}_Previews. Це не є обов’язковою вимогою компілятора, але покращує читабельність і навігацію проектом. Xcode автоматично підставляє цей шаблон при створенні нового файлу SwiftUI.
Механізм роботи PreviewProvider базується на статичній диспетчеризації: Xcode компілює extension з PreviewProvider тільки для Debug-конфігурації та викликає previews у процесі побудови Canvas. Щоразу при зміні коду Xcode перекомпілює лише змінені PreviewProvider, що забезпечує майже миттєве оновлення попереднього перегляду.
SwiftUI не гарантує точної відповідності попереднього перегляду фінальному інтерфейсу на симуляторі або пристрої — Canvas використовує спрощений рендеринг. Анімації із затримками можуть відображатися некоректно, а деякі UIKit-компоненти (MapKit, WebView) не рендеряться в Canvas без додаткового налаштування.
Group дозволяє відобразити кілька станів однієї View одночасно, що прискорює ітерацію при верстці різних конфігурацій. Кожен попередній перегляд всередині Group рендериться незалежно.
struct ButtonView_Previews: PreviewProvider {
static var previews: some View {
Group {
ButtonView(title: "Primary", style: .primary)
.previewDisplayName("Primary")
ButtonView(title: "Disabled", style: .primary)
.disabled(true)
.previewDisplayName("Disabled")
ButtonView(title: "Secondary", style: .secondary)
.previewDisplayName("Secondary")
}
}
}
previewDisplayName додає підпис до кожного попереднього перегляду в Canvas, що особливо зручно при порівнянні кількох станів. Максимальна кількість попередніх переглядів у Group не обмежена, але більш ніж 6–8 сповільнюють Canvas.
Xcode надає кілька модифікаторів для налаштування відображення попереднього перегляду. Основні: previewDevice — емулює конкретний пристрій (iPhone 16 Pro, iPad Air, Apple Watch Ultra), previewLayout — задає розмір (device, fixed, sizeThatFits). Комбінація цих модифікаторів дає повний контроль над середовищем попереднього перегляду.
previewDevice приймає рядок з назвою пристрою, наприклад "iPhone 16 Pro" або "iPad Pro 13-inch (M4)". Список доступних пристроїв залежить від встановлених симуляторів у Xcode. Якщо пристрій не знайдено, Canvas відображає попередній перегляд на пристрої за замовчуванням без помилки.
| Модифікатор | Опис | Приклад |
|---|---|---|
| previewDevice | Емуляція пристрою | .previewDevice("iPhone 16 Pro") |
| previewLayout | Режим розміру | .previewLayout(.sizeThatFits) |
| previewDisplayName | Підпис попереднього перегляду | .previewDisplayName("Dark Mode") |
| preferredColorScheme | Тема оформлення | .preferredColorScheme(.dark) |
| dynamicTypeSize | Розмір шрифту | .dynamicTypeSize(.xxxLarge) |
Поширена практика — показувати одну View на кількох пристроях одночасно, щоб перевірити адаптивність. Для цього використовується ForEach з масивом назв пристроїв.
struct AdaptiveView_Previews: PreviewProvider {
static var previews: some View {
ForEach(["iPhone SE (3rd generation)", "iPhone 16 Pro Max", "iPad Pro 13-inch (M4)"], id: \.self) { device in
AdaptiveView()
.previewDevice(.previewDevice(device))
.previewDisplayName(device)
}
}
}
Практичні приклади показують різні сценарії використання PreviewProvider: від простого попереднього перегляду до складних конфігурацій з живими даними та сумісністю з UIKit.
Мок-дані — стандартний патерн для попереднього перегляду, коли View приймає модель. Замість реального API підставляються тестові дані, що дозволяє візуально перевірити стан інтерфейсу без запуску застосунку.
struct UserProfileView: View {
let user: User
var body: some View {
VStack {
AsyncImage(url: user.avatarURL)
.clipShape(Circle())
Text(user.name)
.font(.title)
Text(user.bio)
.font(.body)
.foregroundColor(.secondary)
}
}
}
struct UserProfileView_Previews: PreviewProvider {
static var previews: some View {
UserProfileView(user: .mock)
.previewDisplayName("Profile")
UserProfileView(user: .mockLongName)
.previewDisplayName("Long Name")
}
}
Сумісність з UIKit — PreviewProvider працює і з UIKit-компонентами, обгорнутими в UIViewRepresentable. Це дозволяє переглядати існуючі UIKit-в’ю в SwiftUI Canvas без міграції всього проекту.
struct MapViewRepresentable: UIViewRepresentable {
func makeUIView(context: Context) -> MKMapView {
MKMapView()
}
func updateUIView(_ uiView: MKMapView, context: Context) {
// Configure map
}
}
struct MapView_Previews: PreviewProvider {
static var previews: some View {
MapViewRepresentable()
}
}
Canvas — це візуальний редактор Xcode, який рендерить результат роботи PreviewProvider у реальному часі. Без реалізації PreviewProvider Canvas залишається порожнім. Canvas і PreviewProvider працюють у парі: PreviewProvider визначає що показувати, Canvas — де і як.
Важливо розуміти: Canvas — це середовище виконання попереднього перегляду, а не альтернатива PreviewProvider. Навіть якщо розробник не відкриває Canvas, PreviewProvider може використовуватися для швидкої перевірки коду через спливаючий попередній перегляд при наведенні на іконку Canvas. За даними WWDC 2024, Apple рекомендує писати PreviewProvider для кожної View як стандарт розробки, аналогічний написанню юніт-тестів.
| Компонент | Роль | Обов’язковість |
|---|---|---|
| PreviewProvider | Визначає вміст попереднього перегляду | Обов’язковий для Canvas |
| Canvas | Рендерить попередній перегляд в редакторі | Опціонально (можна використовувати .preview) |
| SwiftUI View | UI-компонент | Обов’язковий |
Рекомендація: пишіть PreviewProvider для кожної публічної View у проекті. Це прискорює онбординг нових розробників, спрощує code review та дозволяє швидко перевіряти візуальні зміни без збірки всього проекту.
Проблема 1: Попередній перегляд не оновлюється. Якщо Canvas не відображає зміни коду, причина найчастіше в кеші DerivedData. Очистіть DerivedData через Product → Clean Build Folder (⇧⌘K) або вручну видаливши папку ~/Library/Developer/Xcode/DerivedData. Після очищення Canvas перебудовує попередній перегляд заново.
Проблема 2: PreviewProvider не бачить @StateObject. PreviewProvider створює статичний екземпляр View, тому залежності, що вимагають ін’єкції (ViewModels, сервіси), мають передаватися через ініціалізатор або @StateObject зі значенням за замовчуванням. Використовуйте мок-об’єкти замість реальних сервісів у попередніх переглядах.
Проблема 3: Анімації не працюють у Canvas. Canvas не підтримує всі анімації SwiftUI — особливо ті, що залежать від часу (withAnimation із затримкою, .spring). Для перевірки анімацій запускайте застосунок на симуляторі. Canvas підходить для статичної перевірки layout.
Ін’єкція залежностей — найкращий спосіб зробити PreviewProvider працездатним зі складними ViewModel. Створіть окремий екземпляр ViewModel з тестовими даними та передайте його в ініціалізатор View.
struct DashboardView: View {
@StateObject var viewModel: DashboardViewModel
var body: some View {
List(viewModel.items) { item in
Text(item.title)
}
}
}
struct DashboardView_Previews: PreviewProvider {
static var previews: some View {
DashboardView(viewModel: DashboardViewModel.mock)
}
}
Мок-розширення: створіть extension для ViewModel, який надає статичні .mock екземпляри. Це тримає тестові дані поруч із ViewModel та робить PreviewProvider читабельним.
Часті запитання
Технічно ні — застосунок скомпілюється і без PreviewProvider. Однак на практиці Apple та спільнота SwiftUI рекомендують писати попередні перегляди для кожної публічної View. PreviewProvider прискорює розробку, дозволяє швидко перевіряти layout на різних пристроях і служить візуальною документацією для команди.
PreviewProvider додає код тільки в Debug-збірку, тому помилки компіляції можуть виникати, якщо в попередньому перегляді використовуються типи, недоступні в релізній конфігурації. Також помилки виникають при використанні @available з платформами, що не підтримують Canvas, або при перевищенні ліміту складності попереднього перегляду.
Напряму — ніяк, PreviewProvider виконується в ізоляції. Використовуйте мок-дані: створіть статичний extension моделі з .mock-екземплярами. Для View з @StateObject передавайте ViewModel з тестовими даними через ініціалізатор. Це імітує реальні дані без мережевих запитів.
Ні, PreviewProvider не впливає на розмір релізного бінарного файлу. Xcode використовує умовну компіляцію (#if DEBUG / #if !RELEASE) для виключення коду попереднього перегляду з релізної збірки. Код PreviewProvider присутній тільки в Debug-конфігурації і не потрапляє в білд App Store.
Так, Xcode підтримує налагодження попереднього перегляду. Встановіть breakpoint всередині previews або самого коду View і виберіть Product → Preview → Debug Preview. Після цього breakpoint спрацює при рендерингу Canvas. Це корисно для аналізу layout issues, які видно тільки в попередньому перегляді.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також