UIKit là một framework để xây dựng giao diện đồ họa trong các ứng dụng iOS và macOS. Bộ công cụ bao gồm UIView, UIViewController, các thành phần điều khiển và hệ thống Auto Layout, cho phép tạo ra các màn hình thích ứng và tương tác. Theo Apple Developer Documentation (2025), UIKit chứa hơn 200 lớp để làm việc với cửa sổ, view, hoạt ảnh, cử chỉ và văn bản — nó là nền tảng của tất cả các ứng dụng iPhone và iPad.
Những điểm chính
UIKit là một framework của Apple cung cấp các lớp để tạo và quản lý giao diện người dùng trên iOS, iPadOS và macOS (thông qua Mac Catalyst). Nó hoạt động trên nền Core Animation, Core Graphics và Quartz Core, trừu tượng hóa việc render cấp thấp thành các đối tượng cấp cao — nút bấm, nhãn, hình ảnh và bộ chứa. UIKit ra mắt cùng với iPhone OS 1 vào năm 2007 và vẫn là framework chính cho phát triển iOS bên cạnh SwiftUI.
Framework này tuân theo cách tiếp cận mệnh lệnh: nhà phát triển tạo các phiên bản của lớp UIButton, UILabel, UIImageView, đặt thuộc tính của chúng (màu sắc, phông chữ, vị trí) và thêm chúng vào phân cấp view thông qua addSubview. Mọi thay đổi giao diện được thực hiện một cách rõ ràng — không có cập nhật kỳ diệu nào đằng sau hậu trường. Điều này phân biệt UIKit với các framework khai báo như SwiftUI, nơi mô tả trạng thái tự động vẽ lại giao diện.
Framework bao gồm một số danh mục lớp. UIView là thành phần cơ bản mà tất cả các thành phần trực quan kế thừa. UIWindow là bộ chứa cấp cao nhất qua đó các view được hiển thị trên màn hình. UIViewController quản lý một tập hợp các view và phản hồi các thao tác xoay màn hình, xuất hiện bàn phím và thông báo hệ thống. UIApplication là điểm vào xử lý các sự kiện chạm và nhấn nút.
Đối với văn bản, sử dụng UILabel (văn bản tĩnh), UITextField (nhập một dòng), UITextView (nhập nhiều dòng). Đối với nút bấm — UIButton, bao gồm nút hệ thống, tùy chỉnh và biểu tượng SF Symbols. Đối với điều hướng — UINavigationController, UITabBarController và UISplitViewController. Tổng cộng, UIKit có hơn 200 lớp công khai.
Kiến trúc UIKit được xây dựng trên các lớp: mỗi lớp chịu trách nhiệm về một khía cạnh hiển thị riêng. Ở cấp thấp nhất là Core Graphics — công cụ render đường dẫn, văn bản và hình ảnh. Phía trên là Core Animation, quản lý thành phần lớp (CALayer) và hoạt ảnh giữa các trạng thái. UIKit xây dựng một API hướng đối tượng trên chúng: UIView, UIViewController và UIResponder.
Mỗi ứng dụng có một phân cấp view — một cây với gốc là UIWindow. Bên dưới là UIViewController gốc, view của nó và các subview lồng bên trong. Các sự kiện chạm lan truyền dọc theo chuỗi phản hồi: từ view lồng sâu nhất đến các view cha và lên đến UIApplication. Nếu không có đối tượng nào xử lý thao tác chạm, nó sẽ bị bỏ qua.
Mỗi UIView chứa một CALayer xử lý việc render pixel trên màn hình. View quản lý thao tác chạm và khả năng tiếp cận; layer quản lý đồ họa — bóng, cornerRadius, viền, biến đổi. Sự tách biệt này cho phép chuyển đồ họa nặng sang một luồng riêng (máy chủ render) mà không chặn luồng chính. Apple khuyên bạn nên làm việc trực tiếp với CALayer nếu có hơn 200 view trên màn hình — điều này giảm tải CPU.
Chuỗi phản hồi bắt đầu với đối tượng đầu tiên nhận được sự kiện chạm. Nếu nó không xử lý sự kiện (phương thức touchesBegan không được ghi đè), sự kiện sẽ được chuyển đến trình phản hồi tiếp theo trong chuỗi: next, superview, next responder, UIViewController, UIWindow, UIApplication, App Delegate. Điều này cho phép chặn các cử chỉ toàn cục và sự kiện bàn phím ở cấp cảnh mà không cần thêm trình xử lý vào mọi view.
Mỗi UIViewController trải qua một chuỗi sự kiện được xác định chặt chẽ. Vòng đời bao gồm các giai đoạn: khởi tạo, tải view, xuất hiện trên màn hình, cập nhật bố cục khi xoay, ẩn, rời khỏi màn hình và giải phóng bộ nhớ. Nhà phát triển ghi đè các phương thức tương ứng để thực thi mã tùy chỉnh ở mỗi giai đoạn.
class ProfileViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
loadUserProfile()
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
clearCache()
}
}
Trong viewDidLoad, giao diện được cấu hình — subview được tạo, ràng buộc được thiết lập, delegate được đăng ký. Trong viewWillAppear, các thao tác trước khi hiển thị được thực hiện: tải dữ liệu mới từ mạng, cập nhật giá trị. viewDidDisappear là nơi hủy đăng ký thông báo và dọn dẹp dữ liệu tạm thời. Việc gọi super là bắt buộc trong tất cả các ghi đè, nếu không chuỗi sự kiện sẽ bị phá vỡ.
Trong các phiên bản iOS cũ, tồn tại phương thức viewDidUnload, được gọi khi thiếu bộ nhớ. Kể từ iOS 6, phương thức đã bị loại bỏ — UIKit hiện tự động giải phóng view của các bộ điều khiển khi chúng không hiển thị. Nhà phát triển chỉ cần khai báo tất cả tham chiếu view là weak để ARC có thể giải phóng bộ nhớ chính xác khi nhận được cảnh báo hệ thống.
UIKit hỗ trợ hai loại chuyển tiếp: segue (thông qua Storyboard) và điều hướng lập trình qua UINavigationController. Một chuyển tiếp lập trình trông như sau: navigationController?.pushViewController(detailVC, animated: true). Trong trường hợp này, vòng đời của detailVC diễn ra bình thường — viewDidLoad được gọi một lần, viewWillAppear được gọi mỗi khi nó xuất hiện.
Auto Layout là một hệ thống định vị dựa trên các mối quan hệ toán học (ràng buộc). Thay vì tọa độ X và Y được mã hóa cứng, nhà phát triển mô tả các quy tắc: “nút nằm bên phải nhãn với khoảng cách 16pt” hoặc “view mở rộng theo chiều rộng màn hình với lề 20pt bên trái và bên phải.” Hệ thống giải hệ phương trình kết quả tại thời điểm chạy, thích ứng giao diện với mọi kích thước màn hình.
Các ràng buộc có thể được đặt trong Interface Builder (thông qua kéo và thả) hoặc theo cách lập trình trong Swift. Mỗi ràng buộc là một phiên bản của lớp NSLayoutConstraint với các tham số: firstItem, firstAttribute, relation, secondItem, secondAttribute, multiplier, constant. Các ràng buộc được kích hoạt qua isActive = true hoặc hàng loạt qua NSLayoutConstraint.activate().
Với sự ra đời của iPhone X (2017), Apple đã giới thiệu Safe Area — khu vực màn hình không có notch, góc bo tròn và chỉ báo thanh chủ. Các ràng buộc nên được gắn vào view.safeAreaLayoutGuide, không phải view. Layout Margins thêm phần đệm bên trong cho view, mặc định là 8pt hoặc 16pt tùy theo ngữ cảnh. Sử dụng safeAreaLayoutGuide đảm bảo hiển thị chính xác trên tất cả các thế hệ iPhone và iPad.
Auto Layout hỗ trợ hoạt ảnh bằng cách thay đổi hằng số ràng buộc. Chỉ cần cập nhật constant của một ràng buộc và gọi UIView.animate với layoutIfNeeded bên trong khối hoạt ảnh. Hệ thống tính toán lại mượt mà vị trí của tất cả các view trong phân cấp. Kỹ thuật này được sử dụng cho các khối mở rộng, bảng điều khiển bàn phím thích ứng và thay đổi hướng màn hình.
UITableView và UICollectionView là hai công cụ mạnh mẽ của UIKit để hiển thị danh sách và lưới. UITableView phù hợp cho danh sách dọc một cột (trò chuyện, cài đặt, bảng tin). UICollectionView dành cho lưới, danh sách ngang, băng chuyền và bố cục tùy chỉnh (thư viện ảnh, sản phẩm, lịch). Cả hai lớp đều sử dụng mẫu ủy quyền để tách dữ liệu khỏi giao diện.
Nguồn dữ liệu là giao thức UITableViewDataSource với các phương thức bắt buộc numberOfRowsInSection và cellForRowAt. UITableViewDelegate xử lý các thao tác chạm vào ô, chiều cao hàng và sự kiện cuộn. Cơ chế định danh tái sử dụng tái sử dụng các ô đã trôi ra khỏi màn hình, điều này rất quan trọng đối với hiệu suất trên danh sách lớn.
class ContactsViewController: UITableViewController {
private let contacts = ["Anna", "Boris", "Victor"]
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self,
forCellReuseIdentifier: "cell")
}
override func tableView(_ tableView: UITableView,
numberOfRowsInSection section: Int) -> Int {
return contacts.count
}
override func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell",
for: indexPath)
var content = cell.defaultContentConfiguration()
content.text = contacts[indexPath.row]
cell.contentConfiguration = content
return cell
}
}
Ví dụ cho thấy một bộ điều khiển tối thiểu để hiển thị một mảng chuỗi. Ô được cấu hình thông qua UIListContentConfiguration — một API hiện đại (iOS 14+) đã thay thế textLabel và detailTextLabel lỗi thời. Việc đăng ký lớp ô trong viewDidLoad là bắt buộc, nếu không ứng dụng sẽ gặp sự cố với ngoại lệ thời gian chạy.
Bắt đầu từ iOS 13, Apple khuyến nghị UICollectionViewCompositionalLayout để xây dựng các bố cục phức tạp. Nhà phát triển mô tả phần, nhóm, mục và kích thước của chúng một cách khai báo — kết quả là một lưới với hình học tùy ý: dải, lưới 2x2, băng chuyền hoặc trang trí. Compositional Layout đã thay thế UICollectionViewFlowLayout lỗi thời cho tất cả các dự án mới. Kết hợp với DiffableDataSource, việc cập nhật bộ sưu tập được giảm xuống một lần gọi apply(snapshot) duy nhất và hoạt ảnh thay đổi được thực hiện tự động.
Dưới đây là hai ví dụ thực tế về việc sử dụng UIKit trong các tác vụ thực tế: tạo một view tùy chỉnh có bóng và góc bo tròn, và xử lý cử chỉ vuốt để xóa một mục khỏi danh sách.
extension UIView {
func applyCardStyle() {
layer.cornerRadius = 12
layer.shadowOpacity = 0.15
layer.shadowRadius = 8
layer.shadowOffset = CGSize(width: 0, height: 2)
layer.masksToBounds = false
}
}
@objc private func handleSwipe(_ gesture: UISwipeGestureRecognizer) {
guard let swipedView = gesture.view else { return }
UIView.animate(withDuration: 0.3) {
swipedView.alpha = 0
swipedView.transform = CGAffineTransform(translationX: 300, y: 0)
} completion: { _ in
swipedView.removeFromSuperview()
}
}
Phần mở rộng applyCardStyle thêm bóng và góc bo tròn cho bất kỳ view nào — hữu ích cho thẻ sản phẩm, hồ sơ và thông báo. Phương thức handleSwipe với hoạt ảnh xóa một mục khi người dùng vuốt sang phải trên đó. Trình xử lý được thêm vào view thông qua addGestureRecognizer với cấu hình UISwipeGestureRecognizer(direction: .right). Việc đặt masksToBounds = false rất quan trọng để ngăn bóng bị cắt bởi ranh giới view.
Đối với các giao diện phức tạp hơn, hãy sử dụng UIStackView — một bộ chứa tự động phân phối các view lồng nhau theo chiều ngang hoặc chiều dọc. Stack View đơn giản hóa bố cục: không cần đặt ràng buộc cho từng thành phần, chỉ cần một ràng buộc cho chính stack.
Câu hỏi thường gặp
Frame là hình chữ nhật trong tọa độ superview (vị trí + kích thước). Bounds là hình chữ nhật trong tọa độ riêng của view (luôn bắt đầu từ 0,0). Frame thay đổi khi xoay và thu phóng; bounds thì không.
UIKit tự động giải phóng view của các bộ điều khiển bị ẩn. Nhà phát triển chỉ cần khai báo thuộc tính view là weak var để ARC có thể giải phóng bộ nhớ khi nhận được cảnh báo hệ thống.
Đối với các dự án mới, Apple khuyến nghị SwiftUI. Nếu dự án sử dụng UIKit — hãy sử dụng XIB cho các màn hình riêng lẻ hoặc bố cục lập trình qua SnapKit. Storyboard tạo ra xung đột hợp nhất và làm chậm quá trình xây dựng.
Sử dụng UIColor với hỗ trợ traitCollection: UIColor { $0.userInterfaceStyle == .dark ? ... : ... }. Kích hoạt Chế độ tối trong Info.plist bằng khóa UIUserInterfaceStyle.
UIStackView tự động tính toán vị trí và kích thước của các view lồng nhau dựa trên alignment, distribution và spacing. Nó giảm mã ràng buộc từ 60–80% và đơn giản hóa việc thích ứng với các màn hình khác nhau.
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