PreviewProvider là một giao thức SwiftUI xác định điểm đầu vào để tạo bản xem trước trong Xcode Canvas. Việc triển khai giao thức cho phép nhà phát triển xem giao diện mà không cần khởi động trình mô phỏng, tăng tốc độ lặp lại trong giai đoạn bố trí. Theo Apple Developer Documentation (2026), PreviewProvider là bắt buộc đối với tất cả SwiftUI View nếu dự án sử dụng Canvas — nếu không có nó, Canvas sẽ không hiển thị giao diện người dùng. Tìm hiểu thêm trong bài viết về SwiftUI.
Chính
PreviewProvider là một giao thức SwiftUI xác định hợp đồng để tạo nội dung xem trước trong Xcode Canvas. Giao thức chứa một thuộc tính bắt buộc duy nhất: previews kiểu some View. Bất kỳ giá trị nào được previews trả về đều được hiển thị trong Canvas dưới dạng bản xem trước tương tác. PreviewProvider không yêu cầu kế thừa — chỉ cần triển khai tĩnh trong một extension.
Về mặt kiến trúc, PreviewProvider không phải là một phần của runtime SwiftUI — nó hoàn toàn là một công cụ phát triển. Giao thức được đánh dấu bằng thuộc tính @available(iOS 13.0, *) và không được biên dịch trong bản phát hành, vì Xcode sử dụng biên dịch có điều kiện để loại trừ mã xem trước khỏi sản phẩm. Điều này có nghĩa là PreviewProvider không ảnh hưởng đến kích thước tệp nhị phân hoặc hiệu suất ứng dụng.
Thuộc tính previews là yêu cầu duy nhất của PreviewProvider. Nó phải trả về bất kỳ View nào: từ Text đơn giản đến hệ thống phân cấp phức tạp với Group và ForEach. Xcode kết xuất View được trả về trong Canvas, áp dụng cài đặt hệ thống (chủ đề, kích thước, phông chữ).
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")
}
}
Quy ước đặt tên: Apple khuyên bạn nên đặt tên cấu trúc xem trước là {ViewName}_Previews. Đây không phải là yêu cầu của trình biên dịch, nhưng nó cải thiện khả năng đọc và điều hướng dự án. Xcode tự động chèn mẫu này khi tạo tệp SwiftUI mới.
Cơ chế hoạt động của PreviewProvider dựa trên điều phối tĩnh: Xcode biên dịch extension PreviewProvider chỉ cho cấu hình Debug và gọi previews trong quá trình xây dựng Canvas. Mỗi khi mã thay đổi, Xcode chỉ biên dịch lại các PreviewProvider đã sửa đổi, đảm bảo cập nhật bản xem trước gần như tức thì.
SwiftUI không đảm bảo sự khớp chính xác giữa bản xem trước và giao diện người dùng cuối cùng trên trình mô phỏng hoặc thiết bị — Canvas sử dụng kết xuất đơn giản hóa. Hoạt ảnh có độ trễ có thể hiển thị không chính xác và một số thành phần UIKit (MapKit, WebView) không kết xuất trong Canvas nếu không có cấu hình bổ sung.
Group cho phép hiển thị đồng thời nhiều trạng thái của một View, tăng tốc độ lặp lại khi bố trí các cấu hình khác nhau. Mỗi bản xem trước trong Group được kết xuất độc lập.
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 thêm nhãn cho mỗi bản xem trước trong Canvas, đặc biệt hữu ích khi so sánh nhiều trạng thái. Số lượng bản xem trước tối đa trong Group không bị giới hạn, nhưng hơn 6–8 sẽ làm chậm Canvas.
Xcode cung cấp một số bổ ngữ để cấu hình hiển thị bản xem trước. Các bổ ngữ chính: previewDevice — mô phỏng một thiết bị cụ thể (iPhone 16 Pro, iPad Air, Apple Watch Ultra), previewLayout — đặt kích thước (device, fixed, sizeThatFits). Sự kết hợp của các bổ ngữ này mang lại toàn quyền kiểm soát môi trường xem trước.
previewDevice chấp nhận một chuỗi có tên thiết bị, ví dụ "iPhone 16 Pro" hoặc "iPad Pro 13-inch (M4)". Danh sách các thiết bị khả dụng phụ thuộc vào trình mô phỏng được cài đặt trong Xcode. Nếu không tìm thấy thiết bị, Canvas sẽ hiển thị bản xem trước trên thiết bị mặc định mà không có lỗi.
| Bổ ngữ | Mô tả | Ví dụ |
|---|---|---|
| previewDevice | Mô phỏng thiết bị | .previewDevice("iPhone 16 Pro") |
| previewLayout | Chế độ kích thước | .previewLayout(.sizeThatFits) |
| previewDisplayName | Nhãn bản xem trước | .previewDisplayName("Dark Mode") |
| preferredColorScheme | Lược đồ màu | .preferredColorScheme(.dark) |
| dynamicTypeSize | Kích thước phông chữ | .dynamicTypeSize(.xxxLarge) |
Thông lệ phổ biến là hiển thị một View trên nhiều thiết bị cùng lúc để kiểm tra khả năng thích ứng. Để làm điều này, hãy sử dụng ForEach với một mảng tên thiết bị.
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)
}
}
}
Các ví dụ thực tế cho thấy các kịch bản sử dụng PreviewProvider khác nhau: từ bản xem trước đơn giản đến cấu hình phức tạp với dữ liệu trực tiếp và tương thích UIKit.
Dữ liệu giả là một mẫu tiêu chuẩn cho bản xem trước khi View chấp nhận một mô hình. Thay vì API thực, dữ liệu thử nghiệm được thay thế, cho phép xác minh trực quan trạng thái giao diện người dùng mà không cần khởi động ứng dụng.
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")
}
}
Tương thích UIKit — PreviewProvider cũng hoạt động với các thành phần UIKit được bọc trong UIViewRepresentable. Điều này cho phép xem trước các UIKit View hiện có trong SwiftUI Canvas mà không cần di chuyển toàn bộ dự án.
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 là trình chỉnh sửa trực quan của Xcode kết xuất đầu ra của PreviewProvider trong thời gian thực. Nếu không có triển khai PreviewProvider, Canvas sẽ trống. Canvas và PreviewProvider hoạt động như một cặp: PreviewProvider xác định nội dung hiển thị, Canvas xác định vị trí và cách thức.
Điều quan trọng là: Canvas là môi trường thực thi bản xem trước, không phải là giải pháp thay thế cho PreviewProvider. Ngay cả khi nhà phát triển không mở Canvas, PreviewProvider vẫn có thể được sử dụng để kiểm tra mã nhanh qua bản xem trước bật lên khi di chuột qua biểu tượng Canvas. Theo WWDC 2024, Apple khuyên bạn nên viết PreviewProvider cho mọi View như một tiêu chuẩn phát triển, tương tự như viết kiểm thử đơn vị.
| Thành phần | Vai trò | Bắt buộc |
|---|---|---|
| PreviewProvider | Xác định nội dung xem trước | Bắt buộc cho Canvas |
| Canvas | Kết xuất bản xem trước trong trình chỉnh sửa | Tùy chọn (có thể dùng .preview) |
| SwiftUI View | Thành phần giao diện | Bắt buộc |
Khuyến nghị: hãy viết PreviewProvider cho mọi View công khai trong dự án. Điều này tăng tốc quá trình giới thiệu cho nhà phát triển mới, đơn giản hóa việc đánh giá mã và cho phép xác minh nhanh các thay đổi trực quan mà không cần xây dựng toàn bộ dự án.
Vấn đề 1: Bản xem trước không cập nhật. Nếu Canvas không phản ánh các thay đổi mã, nguyên nhân thường là bộ nhớ cache DerivedData. Xóa DerivedData qua Product → Clean Build Folder (⇧⌘K) hoặc xóa thủ công thư mục ~/Library/Developer/Xcode/DerivedData. Sau khi xóa, Canvas xây dựng lại bản xem trước từ đầu.
Vấn đề 2: PreviewProvider không thấy @StateObject. PreviewProvider tạo một phiên bản tĩnh của View, do đó các phụ thuộc yêu cầu tiêm (ViewModels, dịch vụ) phải được truyền qua trình khởi tạo hoặc @StateObject với giá trị mặc định. Sử dụng các đối tượng giả thay vì dịch vụ thực trong bản xem trước.
Vấn đề 3: Hoạt ảnh không hoạt động trong Canvas. Canvas không hỗ trợ tất cả hoạt ảnh SwiftUI — đặc biệt là những hoạt ảnh phụ thuộc vào thời gian (withAnimation có độ trễ, .spring). Để kiểm tra hoạt ảnh, hãy chạy ứng dụng trên trình mô phỏng. Canvas phù hợp để xác minh bố cục tĩnh.
Tiêm phụ thuộc là cách tốt nhất để làm cho PreviewProvider hoạt động với ViewModels phức tạp. Tạo một phiên bản ViewModel riêng biệt với dữ liệu thử nghiệm và truyền nó cho trình khởi tạo 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 giả: tạo một extension cho ViewModel cung cấp các phiên bản .mock tĩnh. Điều này giữ dữ liệu thử nghiệm gần với ViewModel và làm cho PreviewProvider dễ đọc.
Câu hỏi thường gặp
Về mặt kỹ thuật là không — ứng dụng sẽ biên dịch mà không có PreviewProvider. Tuy nhiên, trên thực tế, Apple và cộng đồng SwiftUI khuyên bạn nên viết bản xem trước cho mọi View công khai. PreviewProvider tăng tốc phát triển, cho phép kiểm tra bố cục nhanh trên các thiết bị khác nhau và đóng vai trò là tài liệu trực quan cho nhóm.
PreviewProvider chỉ thêm mã trong bản dựng Debug, do đó lỗi biên dịch có thể xảy ra nếu bản xem trước sử dụng các loại không khả dụng trong cấu hình phát hành. Lỗi cũng xảy ra khi sử dụng @available với các nền tảng không hỗ trợ Canvas hoặc khi vượt quá giới hạn độ phức tạp của bản xem trước.
Trực tiếp — không thể, PreviewProvider chạy trong sự cô lập. Sử dụng dữ liệu giả: tạo một extension tĩnh của mô hình với các phiên bản .mock. Đối với View có @StateObject, hãy truyền ViewModel với dữ liệu thử nghiệm qua trình khởi tạo. Điều này mô phỏng dữ liệu thực mà không cần yêu cầu mạng.
Không, PreviewProvider không ảnh hưởng đến kích thước tệp nhị phân phát hành. Xcode sử dụng biên dịch có điều kiện (#if DEBUG / #if !RELEASE) để loại trừ mã xem trước khỏi bản dựng phát hành. Mã PreviewProvider chỉ tồn tại trong cấu hình Debug và không xuất hiện trong bản dựng App Store.
Có, Xcode hỗ trợ gỡ lỗi bản xem trước. Đặt điểm dừng bên trong previews hoặc mã View và chọn Product → Preview → Debug Preview. Điểm dừng sẽ kích hoạt trong quá trình kết xuất Canvas. Điều này hữu ích để phân tích các vấn đề bố cục chỉ hiển thị trong bản xem trước.
Tổng kết
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm