Thêm Pull-to-Refresh một cách đơn giản cho TableView và CollectionView

Pull to Refresh là 1 trong những thành phần giao diện phổ biến thường được sử dụng để làm mới nội dung, data trên 1 TableView hoặc CollectionView. Đây là 1 UI rất tiện lợi và đơn giản để sử dụng và sử dụng rộng rãi. Thao tác thực hiện rất đơn giản, bạn chỉ cần vuốt màn hình xuống để tải lại dữ liệu cho TableView và CollectionView.

Bài viết dưới đây sẽ giúp bạn làm 1 ứng dụng nho nhỏ để làm quen với thành phần giao diện này.

Chuẩn bị

Ý tưởng của ứng dụng hết sức đơn giản, ứng dụng có 1 màn hình với 1 Table View với 1 Row. Trên row này có 1 label hiển thị 1 con số (ban đầu sẽ là số 0). Mỗi lần bạn Pull-to-Refresh (vuốt kéo table view xuống) sẽ xuất hiện 1 IndicatorView thể hiện việc loading data, lúc này con số sẽ được cộng thêm 1 và cập nhật vào label. Sau khi dữ liệu được cập nhật vào table view thì IndicatorView sẽ biến mất và việc refresh data hoàn tất.

Bạn có thể download source code được đính kèm cuối bài viết tôi đã chuẩn bị để chúng ta có thể bắt đầu.

Tạo Refresh Control

Mở project Starter và chọn file ViewController.swift, việc đầu tiên bạn cần làm là khởi tạo 1 instance của UIRefreshControl. Bạn thêm dòng lệnh sau ngay bên dưới khai báo Outlet tableView.

private let refreshControl = UIRefreshControl()

Lúc này refreshControl chúng ta vừa khởi tạo chưa nằm trong hệ thống view của ứng dụng. Vì vậy chúng ta cần thêm nó vào table view. Thêm đoạn code sau vào dưới cùng trong hàm viewDidLoad()

// Add Refresh Control to Table View
if #available(iOS 10.0, *) {
    self.tableView.refreshControl = refreshControl
} else {
    self.tableView.addSubview(refreshControl)
}

Từ iOS 10, UITableView và UICollectionView đã có sẵn thuộc tính refreshControl, nên chúng ta chỉ cần gán đối tượng refreshControl mà chúng ta đã khởi tạo cho thuộc tính đó. Nếu ứng dụng của bạn hỗ trợ cho cả trước iOS 10 thì bạn phải thêm refreshControl là addSubview của tableView.

Thêm Target và Action cho refreshControl

Lúc này, bạn đã thêm refreshControl thành công cho tableView, tuy nhiên nếu bạn Build và Run ứng dụng lúc này thì khi bạn Pull-to-Refresh thì bạn chỉ nhận được 1 IndicatorView quay trên màn hình mà thôi. Nguyên nhân là bạn mới chỉ thêm refreshControl cho tableView nhưng chưa chỉ định cho nó những nhiệm vụ cần thực thi khi Pull-to-Refresh. Để thêm Target và Action cho refreshControl, bạn thêm đoạn code sau trong hàm viewDidLoad()

// Setup Refresh Control
self.refreshControl.addTarget(self, action: #selector(updateData), for: .valueChanged)

Với đoạn code này, bạn chỉ định cho refreshControl biết mỗi lần Pull-to-Refresh thì gọi đến hàm updateData()

Khai báo hàm sau trong ViewController:

@objc private func updateData() {
    self.number += 1
    self.tableView.reloadData()
    self.refreshControl.endRefreshing()
}

Mỗi lần Pull-to-Refresh thì number sẽ cộng thêm 1, sau đó bạn cần gọi hàm reloadData() để cập nhật lại data cho tableView. Cuối cùng bạn gọi hàm endRefreshing() cho refreshControl để chỉ định cho nó biết việc refresh dữ liệu đã kết thúc (nếu ko gọi hàm endRefreshing() thì IndicatorView vẫn sẽ quay vì refreshControl vẫn hiểu là quá trình refresh vẫn chưa kết thúc).

Tùy chỉnh Refresh Control

Như vậy bạn đã tạo 1 Refresh Control để thực hiện hành động Pull-to-Refresh, tuy nhiên bạn chưa hài lòng với giao diện mặc định của nó. Bạn có thể chỉnh sửa 1 chút để giao diện Refresh Control trông bắt mắt hơn. Thêm đoạn code sau trong hàm viewDidLoad()

// Customizing Refresh Control
self.refreshControl.tintColor = UIColor.lightGray
let attributes = [NSForegroundColorAttributeName: UIColor.lightGray]
self.refreshControl.attributedTitle = NSAttributedString(string: "Refreshing Data...", attributes: attributes)

Trên đây là 1 bài hướng dẫn đơn giản để thêm chức năng Pull-to-Refresh cho TableView (cũng tương tự với CollectionView). Hy vọng bài viết trên sẽ giúp ích cho bạn trong quá trình xây dựng ứng dụng iOS.

Source code: https://goo.gl/yfQN7b