Created
January 17, 2020 23:20
-
-
Save 0xLeif/cf6da14282dee2c1127d2ffa54fab18d to your computer and use it in GitHub Desktop.
LazyTable
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class LazyTable: UITableView { | |
fileprivate var loadThreshold: CGFloat = 0.75 // 75% | |
fileprivate var loadAmount: Int = 25 | |
fileprivate var loadCount: Int = 1 | |
fileprivate var batchCount: Int { | |
return loadAmount * loadCount | |
} | |
fileprivate var elements: [UIView] = [] { | |
didSet { | |
if loadAmount > elements.count { | |
reloadData() | |
} | |
} | |
} | |
private var configureCell: ((UITableViewCell) -> Void)? | |
init(style: UITableView.Style = .plain) { | |
super.init(frame: .zero, style: style) | |
delegate = self | |
dataSource = self | |
// TODO: Params | |
estimatedRowHeight = 100 | |
// rowHeight = 120 | |
register(UITableViewCell.self, forCellReuseIdentifier: "cell") | |
} | |
required init?(coder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
private func reload() { | |
if elements.count >= batchCount { | |
loadCount += 1 | |
print("Load Count: \(loadCount)") | |
} | |
reloadData() | |
} | |
} | |
extension LazyTable: UITableViewDelegate { | |
func scrollViewDidScroll(_ scrollView: UIScrollView) { | |
guard scrollView.contentOffset.y > 0 else { | |
return | |
} | |
let percentToBottom = scrollView.contentOffset.y / scrollView.contentSize.height | |
print("Offset: \(scrollView.contentOffset)") | |
print("Height: \(scrollView.contentSize.height)") | |
print("Percent: \(percentToBottom * 100)%") | |
if percentToBottom >= loadThreshold { | |
reload() | |
} | |
} | |
} | |
extension LazyTable: UITableViewDataSource { | |
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { | |
guard batchCount < elements.count else { | |
print("Loading Elements: \(elements.count)") | |
return elements.count + 1 | |
} | |
print("Loading Batch: \(batchCount)") | |
return batchCount + 1 | |
} | |
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { | |
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) | |
guard indexPath.row != elements.count else { | |
cell.contentView.clear() | |
.embed { | |
VStack { | |
[ | |
LoadingView() | |
.configure { $0.color = .blue } | |
.start() | |
] | |
} | |
} | |
return cell | |
} | |
configureCell?(cell) | |
cell.contentView.clear().embed { | |
elements[indexPath.row] | |
} | |
return cell | |
} | |
} | |
extension LazyTable { | |
func add(_ elements: () -> [UIView]) -> Self { | |
self.elements += elements() | |
return self | |
} | |
func configureCell(_ action: @escaping (UITableViewCell) -> Void) -> Self { | |
self.configureCell = action | |
return self | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment