PreviewProvider — protocolul SwiftUI care definește punctul de intrare pentru generarea previzualizărilor în Xcode Canvas. Implementarea protocolului permite dezvoltatorului să vadă interfața fără a porni simulatorul, accelerând iterația în faza de proiectare. Conform Apple Developer Documentation (2026), PreviewProvider este obligatoriu pentru toate SwiftUI View dacă proiectul folosește Canvas — fără el Canvas nu afișează interfața de utilizator. Aflați mai multe în articolul despre SwiftUI.
Principalele puncte
PreviewProvider — protocolul SwiftUI care definește contractul pentru crearea conținutului de previzualizare în Xcode Canvas. Protocolul conține o singură proprietate obligatorie: previews de tipul some View. Orice valoare returnată de previews este afișată în Canvas ca o previzualizare interactivă. PreviewProvider nu necesită moștenire — este suficientă o implementare statică în extension.
Arhitectural, PreviewProvider nu face parte din runtime-ul SwiftUI — este exclusiv un instrument de dezvoltare. Protocolul este marcat cu atributul @available(iOS 13.0, *) și nu se compilează în versiunea release, deoarece Xcode folosește compilarea condiționată pentru a exclude codul de previzualizare din producție. Aceasta înseamnă că PreviewProvider nu afectează dimensiunea binarului și performanța aplicației.
Proprietatea previews — singura cerință a PreviewProvider. Trebuie să returneze orice View: de la un simplu Text până la o ierarhie complexă cu Group și ForEach. Xcode redă View-ul returnat în Canvas, aplicând setările de sistem (temă, dimensiune, font).
import SwiftUI
struct GreetingView: View {
let name: String
var body: some View {
Text("Salut, \(name)!")
.padding()
}
}
// PreviewProvider — implementare statică
struct GreetingView_Previews: PreviewProvider {
static var previews: some View {
GreetingView(name: "World")
}
}
Convenția de denumire: Apple recomandă denumirea structurii de previzualizare ca {ViewName}_Previews. Nu este o cerință obligatorie a compilatorului, dar îmbunătățește lizibilitatea și navigarea în proiect. Xcode înlocuiește automat acest șablon la crearea unui nou fișier SwiftUI.
Mecanismul de funcționare al PreviewProvider se bazează pe expedierea statică: Xcode compilează extensionul cu PreviewProvider numai pentru configurația Debug și apelează previews în timpul construirii Canvas. De fiecare dată când codul se modifică, Xcode recompilează numai PreviewProvider-urile modificate, ceea ce asigură o actualizare aproape instantanee a previzualizării.
SwiftUI nu garantează o potrivire exactă a previzualizării cu UI-ul final pe simulator sau dispozitiv — Canvas folosește randare simplificată. Animațiile cu întârzieri se pot afișa incorect, iar unele componente UIKit (MapKit, WebView) nu se redau în Canvas fără configurare suplimentară.
Group permite afișarea simultană a mai multor stări ale unei singure View, ceea ce accelerează iterația în proiectarea diferitelor configurații. Fiecare previzualizare din interiorul Group este redată independent.
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 adaugă o etichetă la fiecare previzualizare în Canvas, ceea ce este deosebit de util la compararea mai multor stări. Numărul maxim de previzualizări în Group nu este limitat, dar mai mult de 6–8 încetinesc Canvas.
Xcode oferă mai mulți modificatori pentru configurarea afișării previzualizării. Principalii: previewDevice — emulează un dispozitiv specific (iPhone 16 Pro, iPad Air, Apple Watch Ultra), previewLayout — setează dimensiunea (device, fixed, sizeThatFits). Combinația acestor modificatori oferă control total asupra mediului de previzualizare.
previewDevice primește un șir cu numele dispozitivului, de exemplu „iPhone 16 Pro" sau „iPad Pro 13-inch (M4)". Lista dispozitivelor disponibile depinde de simulatoarele instalate în Xcode. Dacă dispozitivul nu este găsit, Canvas afișează previzualizarea pe dispozitivul implicit fără eroare.
| Modificator | Descriere | Exemplu |
|---|---|---|
| previewDevice | Emularea dispozitivului | .previewDevice(„iPhone 16 Pro") |
| previewLayout | Modul dimensiune | .previewLayout(.sizeThatFits) |
| previewDisplayName | Eticheta previzualizării | .previewDisplayName(„Dark Mode") |
| preferredColorScheme | Tema de design | .preferredColorScheme(.dark) |
| dynamicTypeSize | Dimensiunea fontului | .dynamicTypeSize(.xxxLarge) |
Practică comună — afișarea unei singure View pe mai multe dispozitive simultan pentru a verifica adaptabilitatea. Pentru aceasta se folosește ForEach cu un tablou de nume de dispozitive.
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)
}
}
}
Exemple practice arată diferite scenarii de utilizare a PreviewProvider: de la previzualizare simplă la configurații complexe cu date live și compatibilitate UIKit.
Datele simulate — modelul standard pentru previzualizare atunci când View primește un model. În locul API-ului real se substituie date de test, ceea ce permite verificarea vizuală a stării UI fără a porni aplicația.
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")
}
}
Compatibilitatea UIKit — PreviewProvider funcționează și cu componente UIKit înfășurate în UIViewRepresentable. Acest lucru permite previzualizarea vizualizărilor UIKit existente în SwiftUI Canvas fără migrarea întregului proiect.
struct MapViewRepresentable: UIViewRepresentable {
func makeUIView(context: Context) -> MKMapView {
MKMapView()
}
func updateUIView(_ uiView: MKMapView, context: Context) {
// Configurează harta
}
}
struct MapView_Previews: PreviewProvider {
static var previews: some View {
MapViewRepresentable()
}
}
Canvas — este editorul vizual Xcode care redă rezultatul PreviewProvider în timp real. Fără implementarea PreviewProvider, Canvas rămâne gol. Canvas și PreviewProvider lucrează împreună: PreviewProvider determină ce să afișeze, Canvas — unde și cum.
Este important de înțeles: Canvas — este mediul de execuție a previzualizării, nu o alternativă la PreviewProvider. Chiar dacă dezvoltatorul nu deschide Canvas, PreviewProvider poate fi utilizat pentru verificarea rapidă a codului prin previzualizarea care apare la hover pe pictograma Canvas. Conform WWDC 2024, Apple recomandă scrierea PreviewProvider pentru fiecare View ca standard de dezvoltare, similar cu scrierea testelor unitare.
| Componentă | Rol | Obligativitate |
|---|---|---|
| PreviewProvider | Determină conținutul previzualizării | Obligatoriu pentru Canvas |
| Canvas | Redă previzualizarea în editor | Opțional (se poate folosi .preview) |
| SwiftUI View | Component UI | Obligatoriu |
Recomandare: scrieți PreviewProvider pentru fiecare View publică din proiect. Aceasta accelerează integrarea noilor developeri, simplifică code review-ul și permite verificarea rapidă a modificărilor vizuale fără a construi întregul proiect.
Problema 1: Previzualizarea nu se actualizează. Dacă Canvas nu reflectă modificările codului, cauza este de obicei cache-ul DerivedData. Curățați DerivedData prin Product → Clean Build Folder (⇧⌘K) sau ștergând manual folderul ~/Library/Developer/Xcode/DerivedData. După curățare, Canvas reconstruiește previzualizarea de la zero.
Problema 2: PreviewProvider nu vede @StateObject. PreviewProvider creează o instanță statică a View, prin urmare dependențele care necesită injectare (ViewModel, servicii) trebuie transmise prin inițializator sau @StateObject cu valoare implicită. Folosiți obiecte simulate în locul serviciilor reale în previzualizare.
Problema 3: Animațiile nu funcționează în Canvas. Canvas nu suportă toate animațiile SwiftUI — în special cele care depind de timp (withAnimation cu întârziere, .spring). Pentru verificarea animațiilor, rulați aplicația pe simulator. Canvas este potrivit pentru verificarea statică a layout-ului.
Injectarea dependențelor — cea mai bună metodă de a face PreviewProvider funcțional cu ViewModel-uri complexe. Creați o instanță separată a ViewModel cu date de test și transmiteți-o în inițializatorul 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)
}
}
Extensii simulate: creați un extension pentru ViewModel care furnizează instanțe statice .mock. Acest lucru menține datele de test lângă ViewModel și face PreviewProvider lizibil.
Întrebări frecvente
Din punct de vedere tehnic nu — aplicația se compilează și fără PreviewProvider. Cu toate acestea, în practică Apple și comunitatea SwiftUI recomandă scrierea previzualizărilor pentru fiecare View publică. PreviewProvider accelerează dezvoltarea, permite verificarea rapidă a layout-ului pe diferite dispozitive și servește ca documentație vizuală pentru echipă.
PreviewProvider adaugă cod doar în configurația Debug, deci erorile de compilare pot apărea dacă în previzualizare se folosesc tipuri indisponibile în configurația release. Erorile apar și la utilizarea @available cu platforme care nu suportă Canvas sau la depășirea limitei de complexitate a previzualizării.
Direct — nicicum, PreviewProvider rulează în izolare. Utilizați date simulate: creați un extension static al modelului cu instanțe .mock. Pentru View cu @StateObject, transmiteți ViewModel cu date de test prin inițializator. Aceasta simulează date reale fără solicitări de rețea.
Nu, PreviewProvider nu afectează dimensiunea binarului release. Xcode folosește compilarea condiționată (#if DEBUG / #if !RELEASE) pentru a exclude codul de previzualizare din versiunea release. Codul PreviewProvider există doar în configurația Debug și nu ajunge în build-ul App Store.
Da, Xcode suportă depanarea previzualizărilor. Plasați un breakpoint în interiorul previews sau al codului View și selectați Product → Preview → Debug Preview. După aceasta, breakpoint-ul se va declanșa la randarea Canvas. Acest lucru este util pentru analiza problemelor de layout vizibile doar în previzualizare.
Rezumat
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și