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 runtime — това е изключително инструмент за разработка. Протоколът е маркиран с атрибута @available(iOS 13.0, *) и не се компилира в release сборката, тъй като Xcode използва условна компилация за изключване на кода за преглед от продукцията. Това означава, че PreviewProvider не влияе на размера на двоичния файл и производителността на приложението.
Свойството previews — единственото изискване на PreviewProvider. Трябва да върне произволен View: от прост Text до сложна йерархия с Group и ForEach. Xcode рендерира върнатия View в Canvas, прилагайки системните настройки (тема, размер, шрифт).
import SwiftUI
struct GreetingView: View {
let name: String
var body: some View {
Text("Здравейте, \(name)!")
.padding()
}
}
// PreviewProvider — статична имплементация
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 не гарантира точно съответствие на прегледа с крайния UI на симулатора или устройството — 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 съвместимост.
Mock данни — стандартният модел за преглед, когато View приема модел. Вместо реален API се заместват тестови данни, което позволява визуална проверка на състоянието на UI без стартиране на приложението.
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) {
// Конфигуриране на карта
}
}
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 като стандарт за разработка, подобно на писането на unit тестове.
| Компонент | Роля | Задължителност |
|---|---|---|
| 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, следователно зависимостите, изискващи инжекция (ViewModel, услуги), трябва да се предават чрез инициализатор или @StateObject със стойност по подразбиране. Използвайте mock обекти вместо реални услуги в прегледа.
Проблем 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)
}
}
Mock разширения: създайте extension за ViewModel, който предоставя статични .mock екземпляри. Това държи тестовите данни близо до ViewModel и прави PreviewProvider четим.
Често задавани въпроси
Технически не — приложението ще се компилира и без PreviewProvider. На практика обаче Apple и общността на SwiftUI препоръчват писането на прегледи за всяко публично View. PreviewProvider ускорява разработката, позволява бърза проверка на layout на различни устройства и служи като визуална документация за екипа.
PreviewProvider добавя код само в Debug сборката, така че грешки при компилиране могат да възникнат, ако в прегледа се използват типове, недостъпни в release конфигурацията. Грешки възникват и при използване на @available с платформи, които не поддържат Canvas, или при надвишаване на лимита за сложност на прегледа.
Директно — никак, PreviewProvider работи в изолация. Използвайте mock данни: създайте статично extension на модела с .mock екземпляри. За View с @StateObject предайте ViewModel с тестови данни чрез инициализатора. Това симулира реални данни без мрежови заявки.
Не, PreviewProvider не влияе на размера на release двоичния файл. Xcode използва условна компилация (#if DEBUG / #if !RELEASE) за изключване на кода за преглед от release сборката. Кодът на PreviewProvider съществува само в Debug конфигурация и не попада в App Store сборката.
Да, Xcode поддържа дебъгване на прегледи. Поставете breakpoint вътре в previews или в самия код на View и изберете Product → Preview → Debug Preview. След това breakpoint-ът ще се активира при рендериране на Canvas. Това е полезно за анализ на layout проблеми, които са видими само в прегледа.
Резюме
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също