Make SUPER FAST list with UITableView
I wrote a post to show you how I setup UI flexibly with UITableView. Read it here and an example building GrabRewards.
Today, I write about my favorite way to make a dynamic list. I call that knListController
. You will like it.
I learn this way from Brian Voong, at Lets Build That App. Super cool developer you should follow.
You need to view this video before carry on this. Talk to you after 27 mins.
How it works
knListController
is a UIViewController
with UITableView
. You can find why I choose this way instead of UITableViewController
here.
knListController
requires 2 factors when you inherit from it:
- A cell class which inherit from
knListCell
- Data model
knListController
registers your cell, and do the rest for you.
Demo
Download the starter project at branch master
.
In this demo, I do very simple thing step by step to show you how can use knListController
.
Model
struct Book {
var title: String?
var author: String?
init(title: String, author: String) {
self.title = title
self.author = author
}
}
Simple model. You can add other things inside, I don't want to make it become complicated with cover url, published year,...
KISS
principle
Cell
// (1)
class BookCell: knListCell<Book> {
// (2)
override var data: Book? { didSet {
titleLabel.text = data?.title
authorLabel.text = data?.author
}}
// (3)
let titleLabel = UIMaker.makeLabel(font: UIFont.boldSystemFont(ofSize: 17),
color: UIColor.black)
let authorLabel = UIMaker.makeLabel(font: UIFont.systemFont(ofSize: 14),
color: UIColor.gray)
// (4)
override func setupView() {
addSubviews(views: titleLabel, authorLabel)
titleLabel.horizontal(toView: self, space: 24)
titleLabel.bottom(toAnchor: centerYAnchor, space: -4)
authorLabel.horizontal(toView: titleLabel)
authorLabel.verticalSpacing(toView: titleLabel, space: 8)
}
}
(1):
The cell must be inherited from knListCell
, and you have to pass your model into the inheritance. The model you pass into class is the main model of the cell
(2):
Type data
and add didSet
to set data to UI. It's setup already in knListCell
(3) and (4)
This is your UI controls and how to setup layout. You can do anything you want.
Controller
// (1)
class ViewController: knListController<BookCell, Book> {
// (2)
override func setupView() {
rowHeight = 72
view.addFill(tableView)
fetchData()
}
override func fetchData() {
datasource = [
Book(title: "Becoming", author: "Michelle Obama"),
Book(title: "Girl, Wash Your Face: Stop Believing the Lies About Who You Are so You Can Become Who You Were Meant to Be", author: "Rachel Hollis"),
Book(title: "The Wonky Donkey ", author: "Craig Smith"),
Book(title: "Fire and Fury: Inside the Trump White House", author: "Michael Wolff"),
]
}
}
(1):
Controller is inherited from knListController
that required your data type in definition.
It requires your cell type (which inherit from
knListCell
) and your model.
(2):
- You can specific the cell height by set a value to
rowHeight
. - Setup layout for UITableView. Some UI need UITableView fill 3/4 of the screen or specific layout. It's your work.
- Get data from server. You can put it in
viewWillAppear
or somewhere, up to you. - You can set UITableView contentInsets by
contentInset = your_inset
super.setupView()
Time to run
Known issues
- You can't override UITableViewDelegate in your own class.
- Situation: You want to add
tableView:willDisplay:forRowAt
. It doesn't work at all. - Solution: You have to add this function into
knListController
and override in your class. - If you find any solutions, please, PLEASE let me know. I am looking forward to solutions.
- Situation: You want to add
- Not work with Storyboard.
- If you're fan of Storyboard, find solution. Love to from you.
- I am fan of layout by code, no matter with me.
Conclusion
Fast enough? It's fast to me and help me a lot in my work. Hope this can help you.
Completed code is in branch completed
on Github.
Enjoy coding.