IOS Stretchy Headers TableView with MVC

How to Make it Clear and Enjoy Your Code

Tuan Binh
blog.tuanbinh
6 min readJul 27, 2017

--

Hôm nay mình sẽ hướng dẫn các bạn xây dựng ứng dụng đơn giản trong IOS sử dụng Xcode 8 và Swift 3. Mục đích của bài viết này sẽ giúp các bạn
- Cài đặt và custom UITableViewCell sử dụng Xib file
- Áp dụng mô hình MVC
- Mask views sử dụng Core Animation
- Autolayout cơ bản

Sản phẩm cuối cùng trông sẽ giống như vậy.

Cấu trúc project của chúng ta sẽ gồm có:
- SHTableViewController: subclass của UIViewController và chứa UITableView
- SHTableViewDataModelItem:
lưu trữ dữ liệu và hiển thị lên SHTableViewCell
- SHTableViewDataModel:
khởi tạo dữ liệu(nhận dữ liệu từ API) và trả dữ liệu về cho SHTableViewController sử dụng Delegation
- SHTableViewCell:
subclass của UITableViewCell

Đầu tiên chúng ta hãy bắt đầu với SHTableViewCell

Phần 1: TableViewCell

Chúng ta hãy bắt đầu bằng cách tạo project mới trong Xcode chọn “Single View Application” và xoá file ViewController.swift mặc định Xcode đã tạo ra sẵn đi, chúng ta sẽ tạo những file cần thiết sau.

Đầu tiên tạo một UITableViewCell subclass và check vào “Also create XIB file”

Với ví dụ này, Mỗi Cell chỉ hiển thị 2 thông tin là Category và Summary. Vậy đơn giản chỉ cần 2 UILabel, chúng ta sẽ làm như sau.

Add constrain cho view

Tạo outlet cho 2 label trong SHTableViewCell

Tiếp theo, viết cấu trúc dữ liệu cho SHTableViewDataModelItem để hiển thị dữ liệu lên Cell

Từ đó ta viết function configureWithItem hiển thị dữ liệu trong SHTableViewCell

Vậy là đã xong việc cấu hình cho Cell trên Tableview, Tiếp đến chúng ta sẽ tạo TableView

Phần 2: TableView

Đầu tiên, chúng ta tạo một UIViewController subclass:

Tiếp theo, chọn Main.storyboard, ở tab Identity inspector ta gán SHTableViewControler vào custom class

Add UITableView vào storyboard

Cuối cùng, add outlet của tableview vào SHTableViewControler

Chúng ta sẽ tạo ra một mảng SHTableViewDataModelItem để lưu trữ dữ liệu và hiển thị lên tableview

Bây giờ trong viewDidLoad của SHTableViewControler ta cần thực hiện việc load UITableViewCell from Xib files. Thông thường chúng ta sẽ dùng như sau

Thay vì phải “hard-typing the cell identifier” ta sẽ tạo Nib và ReuseIdentifier trong SHTableViewCell

Vậy là xong, ta quay trở lại SHTableViewController. Phương thức registerNib sẽ trở lên đơn giản hơn rất nhiều

Và đừng quên gán delegate và dataSource cho tableview

Nhưng chúng ta vẫn chưa xong, Xcode sẽ báo lỗi như sau “Cannot assign value of type SHTableViewController to type UITableViewDelegate”. Để giải quyết vấn đề này, ta thêm 2 extensions vào SHTableViewController

Sau đó bạn sẽ lại thấy báo thêm một lỗi khác là: “Type SHTableViewController does not conform to protocol UITableViewDataSource”. Lỗi này là do có một vài phương thức yêu cầu bạn phải implement bên trong extension:

Mình sẽ đi nhanh qua phần này, đây sẽ là code đầy đủ của 2 phương thức trên

Vậy là xong, chúng ta đi đến phần cuối: tạo và kết nối DataSource tới Tableview

Phần 3: DataModel

Tạo SHDataModel class.

Trong class này chúng ta sẽ request data từ JSON file hoặc sử dụng HTTP request hay đơn giản hơn là từ “local datasource file”. Trong bài viết này mình sẽ sử dụng “local datasource file” để tạo ra dữ liệu test.

Vậy làm sao để chuyển mảng dữ liệu này lên TableView?

Phần 4: Delegate

Đầu tiên, ta tạo ra một delegate protocol SHTableViewDataModelDelegate bên trong SHTableViewDataModel.swift

Bên trong protocol ta tạo ra một phương thức

Tiếp theo, ta thêm một optional weak property bên trong SHTableViewDataModel class

Sau đây là full code cho class này

Bây giờ chúng ta đã có thể pass data đến tableview

Phần 5: Display Data

Đầu tiên chúng ta phải tạo reference cho DataModel bên trong SHTableViewController:

Tiếp theo, để request data từ Model trong ViewWillAppear chúng ta sẽ viết như sau

Sau đó gán delegate cho dataSource trong ViewDidLoad

Một lần nữa, bạn sẽ thấy Xcode báo lỗi bởi vì SHTableViewController không hề kế thừa từ SHTableViewDataModelDelegate, vì vậy chúng ta cần thêm vào đoạn code sau

Vậy là xong, sau đây là full code của SHTableViewController để giúp các bạn dễ hình dung

Kết quả sau khi chúng ta Build và run

Phần 6: Building the table header

Bây giờ chúng ta sẽ tạo header view cho tableview, các bạn làm như sau

Build và run các bạn sẽ thấy được như hình

Để cố định chiều cao cho headerview chúng ta sẽ define ra 1

Chúng ta không thể sử dụng thuộc tính tableHeaderView của TableView để quản lý table header bởi vì Tableview quản lý frame của table header vì vậy chúng ta sẽ custom lại header của tableview

Tiếp theo trong viewDidLoad chúng ta sẽ viết như sau

Bây giờ chúng ta sẽ define một hằng số cho chiều cao chúng ta sẽ cắt bỏ đi của header view

Tiếp theo chúng ta sẽ thêm CAShapeLayer cho việc masking layer

Trong viewDidLoad chúng ta sẽ viết

Tiếp theo chúng ta sẽ tạo một UIBezierPath để xác định vùng trên header view sẽ bị cắt

Trong hàm updateHeaderView()

Kết quả cuối cùng

Sau đây là full source của SHTableViewController cho các bạn dễ hình dung

Bài viết mình có sử dụng resource của

http://blog.matthewcheok.com/design-teardown-stretchy-headers/

--

--