124 lines
3.2 KiB
Swift
124 lines
3.2 KiB
Swift
|
|
//
|
||
|
|
// CLBaseTableController.swift
|
||
|
|
// Crush
|
||
|
|
//
|
||
|
|
// Created by Leon on 2025/7/20.
|
||
|
|
//
|
||
|
|
|
||
|
|
import UIKit
|
||
|
|
import SnapKit
|
||
|
|
|
||
|
|
class CLBaseTableController: CLBaseViewController, UITableViewDelegate, UITableViewDataSource {
|
||
|
|
// MARK: - Properties
|
||
|
|
var tableView: UITableView!
|
||
|
|
var page: Int = 1
|
||
|
|
var pageSize: Int = 10
|
||
|
|
var datas: [Any] = []
|
||
|
|
|
||
|
|
var listViewDidScrollCallback: ((UIScrollView) -> Void)?
|
||
|
|
|
||
|
|
// MARK: - Lifecycle
|
||
|
|
override func viewDidLoad() {
|
||
|
|
super.viewDidLoad()
|
||
|
|
initData()
|
||
|
|
initUI()
|
||
|
|
}
|
||
|
|
|
||
|
|
// MARK: - Setup
|
||
|
|
private func initData() {
|
||
|
|
page = 1
|
||
|
|
pageSize = 10
|
||
|
|
datas = []
|
||
|
|
}
|
||
|
|
|
||
|
|
private func initUI() {
|
||
|
|
tableView = UITableView(frame: .zero, style: .plain)
|
||
|
|
tableView.separatorStyle = .none
|
||
|
|
tableView.delegate = self
|
||
|
|
tableView.dataSource = self
|
||
|
|
tableView.estimatedRowHeight = 80
|
||
|
|
|
||
|
|
tableView.sectionHeaderHeight = 0
|
||
|
|
tableView.sectionFooterHeight = 0
|
||
|
|
tableView.estimatedSectionHeaderHeight = 0
|
||
|
|
tableView.estimatedSectionFooterHeight = 0
|
||
|
|
|
||
|
|
tableView.backgroundColor = .clear
|
||
|
|
tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: UIWindow.safeAreaBottom + 16, right: 0)
|
||
|
|
tableView.contentInsetAdjustmentBehavior = .never
|
||
|
|
if #available(iOS 15.0, *) {
|
||
|
|
tableView.sectionHeaderTopPadding = 0
|
||
|
|
}
|
||
|
|
view.addSubview(tableView)
|
||
|
|
tableView.snp.makeConstraints { make in
|
||
|
|
make.leading.trailing.top.bottom.equalTo(view)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// MARK: - Public Methods
|
||
|
|
func addRefreshHeaderFooter() {
|
||
|
|
addRefreshHeader()
|
||
|
|
addRefreshFooter()
|
||
|
|
}
|
||
|
|
|
||
|
|
func addRefreshHeader() {
|
||
|
|
RefreshHeaderAnimator { [weak self] in
|
||
|
|
self?.loadNewData()
|
||
|
|
}.link(to: tableView)
|
||
|
|
}
|
||
|
|
|
||
|
|
func addRefreshFooter() {
|
||
|
|
RefreshFooterAnimator { [weak self] in
|
||
|
|
self?.loadMoreData()
|
||
|
|
}.link(to: tableView)
|
||
|
|
}
|
||
|
|
|
||
|
|
func removeRefreshHeader() {
|
||
|
|
tableView.mj_header = nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func removeRefreshFooter() {
|
||
|
|
tableView.mj_footer = nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func loadNewData() {
|
||
|
|
page = 1
|
||
|
|
loadData()
|
||
|
|
}
|
||
|
|
|
||
|
|
func loadMoreData() {
|
||
|
|
page += 1
|
||
|
|
loadData()
|
||
|
|
}
|
||
|
|
|
||
|
|
func loadData() {
|
||
|
|
// To be implemented by subclasses
|
||
|
|
}
|
||
|
|
|
||
|
|
func scrollCurrentContentTop() {
|
||
|
|
tableView.setContentOffset(.zero, animated: true)
|
||
|
|
}
|
||
|
|
|
||
|
|
// MARK: - UITableViewDataSource
|
||
|
|
func numberOfSections(in tableView: UITableView) -> Int {
|
||
|
|
return 1
|
||
|
|
}
|
||
|
|
|
||
|
|
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||
|
|
return datas.count
|
||
|
|
}
|
||
|
|
|
||
|
|
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||
|
|
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") ?? UITableViewCell(style: .default, reuseIdentifier: "cell")
|
||
|
|
return cell
|
||
|
|
}
|
||
|
|
|
||
|
|
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||
|
|
listViewDidScrollCallback?(scrollView)
|
||
|
|
}
|
||
|
|
}
|