Form trong SwiftUI là một thành phần vùng chứa để xây dựng giao diện cài đặt và nhập dữ liệu có cấu trúc, theo thiết kế của Settings trên iOS. Thành phần này tự động nhóm các điều khiển thành các phần với khoảng cách và kiểu hệ thống, giải phóng nhà phát triển khỏi việc điều chỉnh thủ công các dấu phân cách và màu sắc. Theo Tài liệu Apple Developer (2025), Form điều chỉnh giao diện của nó cho từng nền tảng — từ bảng nhóm trên iOS đến danh sách tiêu chuẩn trên macOS — trong khi vẫn duy trì một API thống nhất.
Những điểm chính
Form là một vùng chứa chuyên dụng của SwiftUI được thiết kế để tạo biểu mẫu nhập liệu và màn hình cài đặt. Nó kế thừa hành vi của List nhưng thêm các kiểu dành riêng cho nền tảng: trên iOS, Form hiển thị dưới dạng bảng nhóm với các góc bo tròn của phần; trên macOS, nó xuất hiện dưới dạng danh sách hệ thống tiêu chuẩn với hộp kiểm và điều khiển.
Không giống như bố cục thủ công với VStack và HStack, Form tự động sắp xếp khoảng cách giữa các phần tử, thêm dấu phân cách và điều chỉnh giao diện theo chủ đề hệ thống — sáng hoặc tối. Nhà phát triển chỉ mô tả cấu trúc logic: Section để nhóm và các điều khiển bên trong. Bản thân biểu mẫu quyết định cách bố trí trực quan Picker, Toggle hoặc Stepper trên một nền tảng cụ thể.
Form hỗ trợ tất cả các phần tử nhập liệu tiêu chuẩn của SwiftUI: TextField cho văn bản, SecureField cho mật khẩu, Picker để chọn từ danh sách, Toggle để bật/tắt, Slider cho phạm vi, Stepper cho giá trị tăng dần và DatePicker cho ngày tháng. Mỗi phần tử tự động nhận được kiểu phù hợp với HIG (Human Interface Guidelines) của Apple trên nền tảng mục tiêu.
Mặc dù có sự tương đồng về mặt hình ảnh, Form và List giải quyết các nhiệm vụ khác nhau. List là một vùng chứa phổ quát để hiển thị danh sách dữ liệu có thể cuộn với các thao tác vuốt và chỉnh sửa hàng. Form là một vùng chứa chuyên dụng cho nhập dữ liệu và cài đặt, được tối ưu hóa cho kiểu điều khiển hệ thống.
List phù hợp để hiển thị dữ liệu động: bảng tin, trò chuyện, danh mục sản phẩm. Form dành cho các màn hình tĩnh với tập hợp trường có thể dự đoán trước: hồ sơ người dùng, cài đặt ứng dụng, biểu mẫu đăng ký. Sự khác biệt chính: các phần tử của Form có thể là điều khiển tương tác, trong khi các hàng của List chủ yếu hiển thị dữ liệu và phản hồi khi chạm bằng điều hướng hoặc hành động.
| Tham số | Form | List |
|---|---|---|
| Mục đích | Nhập dữ liệu, cài đặt | Hiển thị danh sách |
| Kiểu phần | Grouped (iOS), hệ thống (macOS) | Plain hoặc Grouped |
| Điều khiển | Picker, Toggle, Slider, Stepper | Hạn chế (nút) |
| Dữ liệu động | Hạn chế (ForEach trong Section) | Hỗ trợ đầy đủ |
| Thao tác vuốt | Có, swipeActions | Có, swipeActions |
Theo Apple Human Interface Guidelines (2025), Form nên được sử dụng cho các màn hình cài đặt và nhập liệu nơi có từ 3 đến 20 điều khiển trên một màn hình và việc chia chúng thành các phần cải thiện khả năng sử dụng.
Section là khối xây dựng chính của Form, cho phép nhóm các phần tử liên quan về mặt logic lại với nhau. Mỗi Section có thể có tiêu đề, chân trang và bất kỳ số lượng điều khiển nào bên trong. Hệ thống tự động thêm khoảng cách giữa các phần và bọc mỗi phần trong một khối trực quan với các góc bo tròn.
Sử dụng Section rất quan trọng đối với khả năng đọc của biểu mẫu: các phần tử được nhóm theo ý nghĩa sẽ dễ dàng hơn cho người dùng xử lý. Ví dụ, trên màn hình cài đặt hồ sơ, có thể tách «Dữ liệu cá nhân», «Thông báo» và «Bảo mật» thành các phần riêng biệt. Mỗi phần có thể chứa chân trang với văn bản giải thích mà hệ thống hiển thị bằng phông chữ nhỏ hơn bên dưới nhóm phần tử.
Form {
Section(header: Text("Hồ sơ")) {
TextField("Tên", text: $name)
TextField("Email", text: $email)
}
Section(header: Text("Thông báo"),
footer: Text("Tắt trong cuộc họp")) {
Toggle("Push notifications", isOn: $pushEnabled)
Toggle("Email notifications", isOn: $emailEnabled)
}
}
Trong ví dụ, phần đầu tiên «Profile» chứa hai trường văn bản không có chân trang, phần thứ hai «Notifications» chứa hai công tắc với giải thích bên dưới nhóm. Chân trang tự động thêm khoảng cách và sử dụng kiểu phông chữ caption. Một Section có thể có chân trang mà không có tiêu đề hoặc tiêu đề mà không có chân trang.
Form hỗ trợ tất cả các phần tử nhập liệu tiêu chuẩn của SwiftUI. Picker trong Form tự động hiển thị dưới dạng hàng điều hướng với chuyển tiếp đến màn hình chọn riêng biệt trên iOS. Toggle xuất hiện dưới dạng hàng với công tắc căn phải. TextField nhận kiểu nhập liệu hệ thống với văn bản giữ chỗ.
Đối với giá trị số, Stepper (thay đổi tăng dần) và Slider (thay đổi mượt trong phạm vi) được sử dụng. DatePicker hỗ trợ nhiều chế độ: date, time, dateAndTime. ColorPicker có sẵn để chọn màu. Mỗi phần tử thích ứng với nền tảng mà không cần mã bổ sung — trên iOS, các điều khiển sử dụng kiểu UIKit gốc; trên macOS, sử dụng AppKit.
| Phần tử | Mục đích | Kiểu trong Form |
|---|---|---|
| TextField | Nhập văn bản | Hàng với văn bản giữ chỗ |
| SecureField | Nhập mật khẩu | Hàng với ký tự ẩn |
| Picker | Chọn từ danh sách | NavigationLink đến màn hình chọn |
| Toggle | Bật/Tắt | Hàng với công tắc |
| Slider | Phạm vi giá trị | Thanh trượt ngang |
| DatePicker | Chọn ngày/giờ | Kiểu nhỏ gọn hoặc bánh xe |
Đối với các điều khiển tùy chỉnh trong Form, có thể sử dụng bất kỳ SwiftUI View nào — chúng kế thừa hành vi tiêu chuẩn của phần. Tuy nhiên, khuyến nghị tuân theo các phần tử hệ thống, vì chúng đảm bảo tuân thủ HIG và hỗ trợ khả năng tiếp cận (VoiceOver, Dynamic Type) mà không cần cấu hình thêm.
Hãy tạo một màn hình đăng ký sử dụng Form. Biểu mẫu chứa bốn phần: dữ liệu cá nhân, chọn vai trò, cài đặt đăng ký và nút gửi. Sử dụng Section để nhóm và các điều khiển SwiftUI tiêu chuẩn.
struct RegistrationForm: View {
@State private var name = ""
@State private var email = ""
@State private var role = "Developer"
@State private var agreedToTerms = false
let roles = ["Developer", "Designer", "Manager"]
var body: some View {
NavigationStack {
Form {
Section(header: Text("Thông tin cá nhân")) {
TextField("Name", text: $name)
TextField("Email", text: $email)
.keyboardType(.emailAddress)
}
Section(header: Text("Vai trò")) {
Picker("Select role", selection: $role) {
ForEach(roles, id: \.self) { role in
Text(role).tag(role)
}
}
}
Section {
Toggle("Agree to terms", isOn: $agreedToTerms)
}
Section {
Button("Đăng ký") {
submitForm()
}
.disabled(!agreedToTerms)
}
}
.navigationTitle("Registration")
}
}
private func submitForm() { }
}
Biểu mẫu được chia thành bốn Section: dữ liệu cá nhân với hai trường văn bản, chọn vai trò qua Picker, đồng ý với điều khoản qua Toggle và nút đăng ký. Nút bị vô hiệu hóa cho đến khi người dùng đồng ý với điều khoản — đây là một ví dụ về xác thực trong Form. NavigationStack thêm tiêu đề và cho phép Picker mở màn hình chọn riêng biệt trên iOS.
struct SettingsForm: View {
@State private var volume: Double = 0.5
@State private var isDarkMode = false
@State private var reminderDate = Date()
var body: some View {
NavigationStack {
Form {
Section(header: Text("Giao diện")) {
Toggle("Dark mode", isOn: $isDarkMode)
Slider(value: $volume, in: 0...1) {
Text("Âm lượng")
}
}
Section(header: Text("Nhắc nhở"),
footer: Text("Bạn sẽ nhận được thông báo vào thời gian đã chọn")) {
DatePicker("Remind at",
selection: $reminderDate,
displayedComponents: .hourAndMinute)
}
Section {
NavigationLink("Advanced Settings",
destination: AdvancedSettingsView())
}
}
.navigationTitle("Settings")
}
}
}
Ví dụ này minh họa sự kết hợp của Slider, DatePicker và NavigationLink trong Form. DatePicker sử dụng chế độ hourAndMinute để chỉ hiển thị thời gian. NavigationLink trong phần cuối cùng tạo chuyển tiếp đến màn hình cài đặt nâng cao — một mẫu phổ biến cho giao diện kiểu Settings. Tiêu đề và chân trang của các phần làm cho biểu mẫu tự giải thích: người dùng hiểu ngay điều khiển nào thuộc nhóm nào.
Câu hỏi thường gặp
Form được tối ưu hóa cho nhập dữ liệu và cài đặt: các điều khiển nhận kiểu hệ thống, các phần nhận góc bo tròn và khoảng cách. List là vùng chứa phổ quát để hiển thị dữ liệu. Form phù hợp cho màn hình cài đặt, List phù hợp cho trò chuyện, bảng tin, danh mục.
Có, Picker trong Form tự động hiển thị dưới dạng hàng với giá trị đã chọn và NavigationLink để chọn danh sách trên iOS. Trên macOS, Picker xuất hiện dưới dạng danh sách thả xuống hoặc nhóm radio tùy theo kiểu. Sự thích ứng diễn ra mà không cần mã bổ sung.
Bất kỳ SwiftUI View nào cũng có thể được đặt trong Form hoặc Section. Đối với các điều khiển tùy chỉnh, khuyến nghị kế thừa khoảng cách tiêu chuẩn của phần và hỗ trợ Dynamic Type thông qua phông chữ hệ thống. Tránh kích thước và màu sắc cố định để biểu mẫu hiển thị chính xác trên tất cả các thiết bị.
Có, Form tự động được bọc trong ScrollView nếu nội dung vượt quá chiều cao màn hình. Không cần thêm ScrollView thủ công — hệ thống tự xác định xem có cần cuộn hay không. Đối với các biểu mẫu không nên cuộn, hãy sử dụng VStack với chiều cao cố định.
Form trên iOS hỗ trợ hai kiểu thông qua bộ điều chỉnh .formStyle(.grouped) — chế độ xem nhóm tiêu chuẩn với các phần bo tròn. Trên macOS, .formStyle(.columns) có sẵn với bố cục nhiều cột. Kiểu được áp dụng cho toàn bộ Form cùng một lúc và thay đổi biểu diễn trực quan của tất cả các phần tử bên trong.
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