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-а: од једноставног прегледа до сложених конфигурација са live подацима и 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 анимације — посебно one које зависе од времена (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. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође