Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A tableview with Swifty style
import UIKit
// Reference: https://medium.com/swift-programming/upgrade-your-tableviews-with-loading-state-in-swift-1fdce34ada77#.w4sg0dwhk
class SwiftyTableView: UIViewController, UITableViewDelegate, UITableViewDataSource {
let tableView: UITableView = UITableView()
let activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView()
var tableState = TableState<String>.Loading {
didSet {
self.tableView.reloadData()
if tableState.loading() {
self.activityIndicator.startAnimating()
} else {
self.activityIndicator.stopAnimating()
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
tableState = .Loading
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2) {
self.tableState = .Error
}
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3) {
self.tableState = .Items(["ad", "asdasd", "asd12312", "12313", "adad", "adasdas13", "123wfsdf"])
}
tableView.translatesAutoresizingMaskIntoConstraints = false
activityIndicator.translatesAutoresizingMaskIntoConstraints = false
tableView.delegate = self
tableView.dataSource = self
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
self.view.addSubview(tableView)
self.view.addSubview(activityIndicator)
activityIndicator.hidesWhenStopped = true
activityIndicator.color = .red
let views = ["tableView": tableView]
self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-64-[tableView]|", options: [], metrics: nil, views: views))
self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[tableView]|", options: [], metrics: nil, views: views))
self.view.addConstraint(NSLayoutConstraint(item: self.activityIndicator, attribute: .centerX, relatedBy: .equal, toItem: self.view, attribute: .centerX, multiplier: 1.0, constant: 0.0))
self.view.addConstraint(NSLayoutConstraint(item: self.activityIndicator, attribute: .centerY, relatedBy: .equal, toItem: self.view, attribute: .centerY, multiplier: 1.0, constant: 0.0))
activityIndicator.startAnimating()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tableState.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = tableState.value(for: indexPath.row)
return cell
}
}
protocol LoadingTableProtocol {
associatedtype CustomLoadingType
func value() -> CustomLoadingType
static func errorValue() -> CustomLoadingType
static func loadingValue() -> CustomLoadingType
}
enum TableState<T: LoadingTableProtocol> {
case Error
case Loading
case Items([T])
var count: Int {
switch self {
case .Items(let stringCollection):
return stringCollection.count
default:
return 1
}
}
func value(for row: Int) -> T.CustomLoadingType {
switch self {
case .Error:
return T.errorValue()
case .Loading:
return T.loadingValue()
case .Items(let stringCollection):
let item = stringCollection[row]
return item.value()
}
}
func loading() -> Bool {
switch self {
case .Loading:
return true
default:
return false
}
}
}
extension String: LoadingTableProtocol {
typealias CustomLoadingType = String
static func errorValue() -> CustomLoadingType {
return "Error"
}
static func loadingValue() -> CustomLoadingType {
return "Loading......"
}
func value() -> CustomLoadingType {
return self
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment