Hiển thị dữ liệu lên TableView trên iOS với Swift trong lập trình iPhone
|Bài này, mình hướng dẫn bạn hiển thị dữ liệu lên TableView trên iOS với Swift trong lập trình ứng dụng cho iPhone. TableView là một trong những điều khiển phổ biến trên các ứng dụng macOS lẫn iOS. Trên Mac, TableView cho phép thể hiện dữ liệu dạng bảng gồm nhiều hàng và cột. Tuy nhiên, trên iOS, do màn hình thiết bị nhỏ, việc hiển thị bảng nhiều cột không phải là tối ưu. Vì vậy, Apple mặc định chỉ cho phép hiển thị một cột và cung cấp một số kiểu để bạn có thể hiển thị thêm thông tin bên cạnh thông tin chính.
Ở dạng đơn giản nhất, TableView hiển thị giống một danh sách:

Apple cũng cung cấp một số dạng hiển thị định nghĩa trước phức tạp hơn, ví dụ:

Và cả tùy biến theo ý thích, nếu các kiểu có sẵn không phù hợp nhu cầu sử dụng của bạn.
Trong iOS, mỗi TableView là một instance của lớp UITableView. Trên macOS, lớp tương ứng là NSTableView. Nếu bạn quan tâm đến việc hiển thị dữ liệu lên Table View với Swift trên macOS, hãy bấm vào đây.
Mình cũng có một bài viết về chủ đề này bằng ngôn ngữ Objective-C. Nếu bạn quan tâm đến việc đổ dữ liệu lên UITableView bằng Objective-C, hãy bấm vào đây.
Chúng ta sẽ cho hiển thị dữ liệu là một danh sách 5 sinh viên có những thuộc tính ID, Name và Address. Dữ liệu sẽ được lưu trong một mảng, sau đó, đổ vào TableView. Khi chạy, màn hình sẽ hiển thị cả ba thông tin, bao gồm Name in đậm ở trên và ID – Address in nhỏ hơn ở ngay dưới Name, như hình:

Hướng dẫn
- Bước 1: Từ Xcode, bấm File > New > Project…
- Bước 2: Chọn iOS > Single View App, bấm Next
- Bước 3:
- Nhập tên Project vào Product Name
- Language chọn Swift
- Bấm Next và chọn nơi lưu Project.
Giao diện
Từ Project navigator, bấm vào file Main.Storyboard. Sau đó bấm vào nút Library, tìm và kéo thả Label vào View.
Chọn Label, ở cửa sổ Attributes inspector, nhập Student List vào bên dưới ô thuộc tính Text Plain. Ở thuộc tính Font, chọn Style Semibold và Size 45.

Bấm nút Add New Constraints, chúng ta sẽ neo Label cố định để nó không bị nhảy lung tung trên những màn hình khác nhau.
Ở cửa sổ Add New Constraints, nhập 0 cho ô trên và 20 cho ô trái, như hình:

Bạn phải đảm bảo hai đoạn thẳng màu đỏ từ 2 ô trên nối vào ô ở giữa hiển thị. Nếu không hiển thị thì bạn bấm vào nó. Xong bấm Add 2 Constraints.
Làm lại như trên, tìm và kéo thả Table View vào View. Neo với Constraints lần lượt là: trên 10, trái, phải và dưới 0.

Kế tiếp, chúng ta sẽ tạo prototype cho mỗi ô hiển thị trên Table View. Cho hiển thị cửa sổ Document Outline, từ Library, tìm và kéo thả Table View Cell vào bên dưới Table View:

Bây giờ, bên trong Table View sẽ xuất hiện phần tử Table View Cell. Bấm vào Table View Cell và mở Attributes inspector, chọn Subtitle cho Style và nhập myCell vào Identifier:

Sau khi xong, bạn sẽ nhìn thấy giao diện thiết kế sẽ hiển thị như hình:

Tạo Connection với mã
Trong mã, chúng ta sẽ thao tác với Table View, do đó, chúng ta sẽ tạo một connection từ giao diện Table View với mã.
Bấm vào nút Assistant editor, phần viết mã của cửa sổ Xcode sẽ bị chia làm hai, một bên là Document Outline, một bên là file code. Mặc định, Xcode sẽ tìm chính xác file code tương ứng, trường hợp này là ViewController.swift, để hiển thị bên phần file code. Nếu vì lí do nào đó cửa sổ code không hiển thị file ViewController.swift, hãy bấm vào nút có hai hình tròn lồng nhau bên trên cửa sổ code và chọn Automatic:

Bấm phải Table View kéo rê chuột vào phần định nghĩa lớp ViewController của file code, bên ngoài tất cả các phương thức. Một cửa sổ popup hiện ra, nhập tên là myTableView, Connection chọn Outlet rồi bấm Connect.

Tạo lớp Student
Chúng ta sẽ tạo lớp Student, mỗi đối tượng của lớp sẽ chứa dữ liệu của một sinh viên lấy từ database. (Mình không bàn việc kết lấy dữ liệu từ database ở bài này). Lớp có 3 thuộc tính ID, Tên và Địa chỉ.
Từ cửa sổ Project navigator, bấm phải thư mục Project, chọn New File… Sau đó, chọn Swift File, đặt tên là Student.swift và viết đoạn mã sau cho file:
import Foundation class Student { var id: String = "" var name: String = "" var address: String = "" init(id: String, name: String, address: String) { self.id = id self.name = name self.address = address } }
Tạo lớp MyData
Lớp này giả lập một model trả dữ liệu từ database lên. Trong lớp này, chúng ta sẽ tạo một class method tên getStudentList trả về một mảng gồm 5 object Student.
Từ cửa sổ Project navigator, bấm phải thư mục Project, chọn New File… Sau đó, chọn Swift File, đặt tên là MyData.swift và viết đoạn mã sau cho file:
import Foundation class MyData { class func getStudentList() -> [Student] { let studentList = [ Student(id: "S01", name: "Anna K. Behrensmeyer", address: "711-2880 Nulla St Mankato Mississippi 96522"), Student(id: "S02", name: "Blaise Pascal", address: "7292 Dictum Av. San Antonio MI 47096"), Student(id: "S03", name: "Caroline Herschel", address: "191-103 Integer Rd. Corona New Mexico 08219"), Student(id: "S04", name: "Cecilia Payne-Gaposchkin", address: "P.O. Box 887 2508 Dolor. Av. Muskegon KY 12482"), Student(id: "S05", name: "Dorothy Hodgkin", address: "935-9940 Tortor. Street Santa Rosa MN 98804") ] return studentList } }
Hiển thị dữ liệu
Để đổ dữ liệu lên TableView, lớp ViewController phải implement protocol UITableViewDataSource và định nghĩa hai phương thức:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
Chúng ta sẽ khai báo biến myData, biến này trỏ đến dữ liệu mà chúng ta muốn sử dụng. Ngoài ra, nhờ implement UITableViewDataSource, chúng ta cũng xác định thuộc tính datasource của TableView là self, tức ViewController.
Mở file code ViewController.swift và viết đoạn mã sau:
import UIKit class ViewController: UIViewController { @IBOutlet weak var myTableView: UITableView! var myData:[Student] = [] override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. myData = MyData.getStudentList() myTableView.dataSource = self } }
Đoạn trên, bạn chưa thấy mình implement protocol UITableViewDataSource. Chúng ta sẽ implement protocol này ngay trong file này, nhưng để dễ nhìn và dễ quản lý mã, mình sẽ tạo một extension để hiện thực protocol. Bạn hình dung đại khái trong trường hợp này, chúng ta viết mã của cùng một lớp ở hai phần khác nhau.
Viết thêm đoạn mã sau vào cuối file ViewController.swift:
extension ViewController: UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return myData.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let studentName = myData[indexPath.row].name let studentIDAndAddress = myData[indexPath.row].id + " - " + myData[indexPath.row].address let myCellID = "myCell" let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: myCellID, for: indexPath) cell.textLabel?.text = studentName cell.detailTextLabel?.text = studentIDAndAddress return cell } }
Như vậy là chúng ta đã hoàn tất việc đổ dữ liệu vào TableView trên iOS với Swift.
Bạn có thể tải xuống project mẫu của mình tại: https://github.com/ngthanhbinh85/Example-UITableView-iOS-Swift