SwiftUI trong phát triển di động: khái niệm, nguyên lý chính và cách hoạt động

Tác giả: IT Sectr Đã đăng: 2026-07-02 Thời gian đọc: 10 phút
SwiftUI là framework khai báo của Apple để xây dựng giao diện trên tất cả các nền tảng. Theo Apple SwiftUI Docs (2025), SwiftUI được sử dụng trong 70% ứng dụng mới trên App Store. Hiểu các khái niệm chính của SwiftUI — View Protocol, @ViewBuilder, NavigationStack — là nền tảng của phát triển iOS hiện đại.

Những điểm chính

  • View Protocol — var body: some View. Mỗi View là một cấu trúc tuân theo giao thức View. body là mô tả giao diện.
  • @ViewBuilder — Result Builder cho nhiều View trong container. if/else, switch, ForEach trong body.
  • NavigationStack (iOS 16+) — điều hướng dựa trên dữ liệu. dựa trên đường dẫn, deep linking. Thay thế NavigationView.
  • @StateObject — quyền sở hữu đối tượng. @ObservedObject — quan sát. @EnvironmentObject — môi trường.
  • @FocusState — quản lý tiêu điểm. .task{}, .onAppear{} — vòng đời. PreviewProvider — xem trước.

Cơ bản (View Protocol, body, some View, @ViewBuilder)

View Protocol là giao thức trung tâm của SwiftUI. Nó yêu cầu một thuộc tính duy nhất: var body: some View. body là thuộc tính tính toán trả về mô tả giao diện. SwiftUI gọi body mỗi khi trạng thái thay đổi và kết xuất kết quả trên GPU.

@ViewBuilder

@ViewBuilder là Result Builder cho View. Cho phép viết nhiều View trong một closure mà không cần return và TupleView. Hỗ trợ if/else, switch, ForEach. Tất cả container (VStack, HStack, ZStack, Group) đều sử dụng @ViewBuilder. Một giải pháp thay thế là Group { … } để nhóm không cần bố cục. some View là Opaque Type. Trình biên dịch biết loại View cụ thể (Text, Button, VStack, v.v.), nhưng trả về bên ngoài dưới dạng some View. Điều này cho phép thay đổi loại body mà không thay đổi chữ ký. ViewModifier — bộ điều chỉnh View: .font(), .padding(), .background(). Bộ điều chỉnh tùy chỉnh thông qua giao thức ViewModifier và .modifier().

swift
// Ví dụ View với @ViewBuilder và NavigationStack
struct ContentView: View {
    @State private var items = ["Item 1", "Item 2"]

    var body: some View {
        NavigationStack {
            List(items, id: .self) { item in
                NavigationLink(item) {
                    DetailView(item: item)
                }
            }
            .navigationTitle("Items")
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button("Add") {
                        items.append("New Item")
                    }
                }
            }
        }
    }
}

// DetailView với @StateObject
struct DetailView: View {
    let item: String
    @StateObject private var viewModel = DetailViewModel()

    var body: some View {
        Text(item)
            .task {
                await viewModel.loadDetails(for: item)
            }
    }
}

Bộ điều chỉnh và container (ViewModifier, NavigationStack, List, Form)

NavigationStack (iOS 16+) — điều hướng dựa trên dữ liệu. Nhận một đường dẫn (mảng các giá trị có thể băm) và hiển thị đích qua navigationDestination. Thay thế NavigationLink với view đích. NavigationLink — nút điều hướng trong ngăn xếp. List — danh sách dọc với phần, vuốt, xóa và kéo thả. Form — List chuyên dụng cho cài đặt: phần, bộ chọn, công tắc, trường văn bản. Section — nhóm trong List/Form với tiêu đề và chân trang. ViewModifier — bộ điều chỉnh tùy chỉnh để tái sử dụng kiểu. .modifier(CustomModifier()) — áp dụng.

List và Form chi tiết

List trong SwiftUI tương đương với UITableView. Hỗ trợ .onDelete, .onMove, .refreshable. SwipeActions — .swipeActions { Button("Xóa", role: .destructive) { } }. Form — tối ưu cho cài đặt: DatePicker, Toggle, Stepper, Picker. Section với header/footer — để nhóm. OutlineGroup — danh sách phân cấp (tương đương UITableView với phần). DisclosureGroup — phần có thể thu gọn với nội dung. IT Sectr khuyên dùng List cho dữ liệu và Form cho cài đặt.

PreviewProvider — giao thức xem trước trong Xcode Canvas. Canvas — xem trước SwiftUI tương tác (yêu cầu @main và Swift 5.9+). @ScaledMetric — kích thước thích ứng mở rộng với Dynamic Type.

Quản lý trạng thái (@StateObject, @ObservedObject, @EnvironmentObject, @FocusState)

Property Wrappers là nền tảng của quản lý trạng thái trong SwiftUI. @State — trạng thái cục bộ (kiểu giá trị). @Binding — kết nối với trạng thái cha. @StateObject — tạo ObservableObject. SwiftUI quản lý vòng đời của đối tượng. @ObservedObject — quan sát ObservableObject bên ngoài. @EnvironmentObject — đối tượng từ môi trường (tiêm phụ thuộc qua .environmentObject()). @Environment — giá trị hệ thống (.colorScheme, .locale). @AppStorage — UserDefaults. @FetchRequest — truy vấn Core Data. @FocusState — tiêu điểm nhập.

Wrapper Mục đích Quyền sở hữu
@StateTrạng thái cục bộ (kiểu giá trị)View sở hữu
@BindingKết nối trạng thái chaCha sở hữu
@StateObjectTạo ObservableObjectView sở hữu
@ObservedObjectQuan sát đối tượng bên ngoàiChủ sở hữu bên ngoài
@EnvironmentObjectĐối tượng từ môi trườngTổ tiên sở hữu
@EnvironmentGiá trị hệ thốngHệ thống
@AppStorageUserDefaultsUserDefaults
@FocusStateTiêu điểm nhậpView sở hữu

@StateObject vs @ObservedObject: @StateObject tạo đối tượng, @ObservedObject quan sát nó. Sử dụng @StateObject để tạo mô hình đầu tiên trong hệ thống phân cấp, @ObservedObject để truyền cho view con. @FocusState — quản lý tiêu điểm: .focused($field, equals: .email). Hỗ trợ enum cho nhiều trường.

Giá trị môi trường và DI

@Environment — giá trị hệ thống: colorScheme, locale, sizeCategory, layoutDirection, managedObjectContext. Giá trị môi trường tùy chỉnh — giá trị tùy chỉnh qua EnvironmentKey. Được sử dụng để tiêm phụ thuộc: chuyển dịch vụ mà không cần tham số rõ ràng. Bộ điều chỉnh .environment() — đặt giá trị trong hệ thống phân cấp. @EnvironmentObject — ObservableObject từ .environmentObject(). Khác với @Environment ở chỗ nó truyền kiểu tham chiếu. IT Sectr khuyên dùng @Environment cho giá trị hệ thống và @EnvironmentObject cho dịch vụ.

Vòng đời (.task, .onAppear, .onDisappear)

.task{} — hoạt động bất đồng bộ khi view xuất hiện. Tự động hủy khi biến mất. Thay thế .onAppear cho async/await. .onAppear{} — hoạt động đồng bộ khi xuất hiện. .onDisappear{} — hoạt động khi biến mất. .onChange(of:) — phản ứng với thay đổi giá trị. .onReceive(Publisher) — phản ứng với nhà xuất bản Combine. Vòng đời View trong SwiftUI: init → onAppear → body (kết xuất) → onDisappear. Khi trạng thái thay đổi: body → diff → kết xuất lại. IT Sectr khuyên dùng .task cho tải bất đồng bộ và .onAppear cho phân tích.

Hoạt ảnh trong SwiftUI

.animation() — bộ điều chỉnh hoạt ảnh. .transition() — hoạt ảnh xuất hiện/biến mất. withAnimation — hoạt ảnh thay đổi trạng thái rõ ràng. matchedGeometryEffect — hoạt ảnh giữa các view khác nhau (hero animation). PhaseAnimator (iOS 17+) — hoạt ảnh đa pha dựa trên enum. KeyframeAnimator (iOS 17+) — hoạt ảnh từng khung hình với keyframes. Hoạt ảnh SwiftUI chạy trên GPU qua Core Animation. IT Sectr khuyên dùng .spring() cho hoạt ảnh tự nhiên và .interpolatingSpring cho hiệu ứng vật lý.

Luồng dữ liệu (Bindings, @Published, ObservableObject)

ObservableObject — giao thức cho đối tượng có thuộc tính @Published. SwiftUI đăng ký nhà xuất bản objectWillChange. @Published — xuất bản thay đổi thuộc tính. @StateObject — tạo ObservableObject, quản lý vòng đời. @ObservedObject — quan sát bên ngoài. Combine — framework cho lập trình phản ứng. @EnvironmentObject — DI qua môi trường. .environmentObject() đặt, @EnvironmentObject đọc. MVVM — kiến trúc tiêu chuẩn: View (SwiftUI) — ViewModel (ObservableObject) — Model. IT Sectr khuyên dùng MVVM + @StateObject cho ViewModels chính.

swift
class UserViewModel: ObservableObject {
    @Published var users: [User] = []
    @Published var isLoading = false

    func loadUsers() async {
        isLoading = true
        defer { isLoading = false }
        do {
            users = try await api.fetchUsers()
        } catch {
            print("Lỗi: \(error)")
        }
    }
}

struct UsersView: View {
    @StateObject private var viewModel = UserViewModel()

    var body: some View {
        List(viewModel.users, id: \.id) { user in
            Text(user.name)
        }
        .task { await viewModel.loadUsers() }
        .overlay {
            if viewModel.isLoading { ProgressView() }
        }
    }
}

Khả năng tiếp cận và bản địa hóa

Khả năng tiếp cận trong SwiftUI: .accessibilityLabel(), .accessibilityHint(), .accessibilityValue(), .accessibilityAddTraits(). VoiceOver đọc nhãn trợ năng. Dynamic Type — @ScaledMetric, @DynamicProperty. Bản địa hóa: String(localized:) (SwiftUI + String Catalog). LocalizedStringKey — dịch tự động. Quy tắc số nhiều — qua String Catalog (one, few, many, other). Phải sang trái (tiếng Ả Rập, tiếng Do Thái) — hỗ trợ tự động. .environment(.layoutDirection, .rightToLeft). IT Sectr khuyên dùng nhãn trợ năng cho tất cả các phần tử tương tác.

swift
struct AccessibleButton: View {
    let action: () -> Void

    var body: some View {
        Button(action: action) {
            Label("Settings", systemImage: "gear")
        }
        .accessibilityLabel("Open Settings")
        .accessibilityHint("Double tap to navigate to settings screen")
        .accessibilityAddTraits(.isButton)
    }
}

// Hỗ trợ Dynamic Type
struct ScalableText: View {
    @ScaledMetric private var fontSize: CGFloat = 17

    var body: some View {
        Text("Hello, World!")
            .font(.system(size: fontSize))
    }
}

Biểu đồ và trực quan hóa (Swift Charts)

Swift Charts (iOS 16+) — framework xây dựng biểu đồ. Chart { } — container cơ bản. BarMark, LineMark, PointMark, AreaMark, RuleMark — dấu. ForEach cho dữ liệu. ChartAxis — tùy chỉnh trục. .chartXAxis, .chartYAxis. ChartLegend — chú giải. Nội suy — catmullRom, linear, step. Hoạt ảnh — .animation() cho Chart. IT Sectr khuyên dùng Swift Charts cho biểu đồ tích hợp và Charts (DGCharts) cho biểu đồ phức tạp.

swift
import Charts

struct MonthlySales: Identifiable {
    let id = UUID()
    let month: String
    let sales: Double
}

struct SalesChart: View {
    let data: [MonthlySales]

    var body: some View {
        Chart(data) { item in
            BarMark(
                x: .value("Month", item.month),
                y: .value("Sales", item.sales)
            )
            .foregroundStyle(.blue.gradient)
        }
        .chartXAxisLabel("Month")
        .chartYAxisLabel("Sales")
        .frame(height: 200)
        .padding()
    }
}

Swift Package Manager (SPM) — trình quản lý phụ thuộc của Apple. Tích hợp trong Xcode. Hỗ trợ: gói nhị phân, tài nguyên, kiểm thử, swift-6 đồng thời nghiêm ngặt. Xuất bản gói qua GitHub với thẻ semver. SPM là tiêu chuẩn thực tế cho phụ thuộc Swift, thay thế CocoaPods và Carthage. IT Sectr khuyên dùng SPM cho tất cả dự án mới.

Swift Concurrency (async/await, TaskGroup, AsyncSequence) — async/await được tích hợp trong Swift 5.5+. Task — đơn vị bất đồng bộ. TaskGroup — tác vụ song song. AsyncSequence — chuỗi bất đồng bộ (AsyncStream, AsyncAlgorithms). Task Local Values — dữ liệu ngữ cảnh cho Task. Swift Concurrency thay thế hoàn toàn Combine cho các hoạt động bất đồng bộ.

Câu hỏi thường gặp

View Protocol trong SwiftUI là gì?

View Protocol là giao thức cơ bản. Yêu cầu var body: some View. body là mô tả giao diện được kết xuất trên GPU.

@ViewBuilder là gì và tại sao cần nó?

@ViewBuilder là Result Builder cho nhiều View. Cho phép if/else, switch, ForEach trong container.

Sự khác biệt giữa @StateObject và @ObservedObject là gì?

@StateObject tạo đối tượng. @ObservedObject quan sát đối tượng hiện có. @StateObject cho lần tạo đầu tiên trong hệ thống phân cấp.

NavigationStack trong iOS 16+ là gì?

NavigationStack — điều hướng dựa trên dữ liệu. dựa trên đường dẫn, deep linking. Thay thế NavigationView.

@FocusState hoạt động như thế nào trong SwiftUI?

@FocusState — quản lý tiêu điểm nhập. Bộ điều chỉnh .focused(). Hỗ trợ enum cho nhiều trường.

Tóm tắt

  • View Protocol — var body: some View. Nền tảng của SwiftUI. Mỗi View là một struct.
  • @ViewBuilder — cú pháp khai báo cho nhiều View. if/else, ForEach trong body.
  • NavigationStack (iOS 16+) — điều hướng hiện đại. data-driven, dựa trên đường dẫn.
  • @StateObject — quyền sở hữu mô hình. @ObservedObject — quan sát. @EnvironmentObject — DI.
  • @FocusState — quản lý tiêu điểm. Hữu ích cho biểu mẫu và nhiều trường nhập.
  • .task{} — hoạt động bất đồng bộ với tự động hủy. .onAppear{} — đồng bộ.
  • PreviewProvider và Canvas — xem trước trong Xcode. @ScaledMetric — kích thước thích ứng.

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.

Thảo luận dự án