177 lines
4.9 KiB
Swift
177 lines
4.9 KiB
Swift
//
|
|
// BlockTableView.swift
|
|
// PatternsSwift
|
|
//
|
|
// Created by mrustaa on 16/04/2020.
|
|
// Copyright © 2020 mrustaa. All rights reserved.
|
|
//
|
|
|
|
import UIKit
|
|
|
|
open class TableAdapterView: UITableView {
|
|
|
|
@IBInspectable var separatorClr: UIColor?
|
|
|
|
public var countCallback: TableAdapterCountCallback?
|
|
public var cellIndexCallback: TableAdapterCellIndexCallback?
|
|
public var heightIndexCallback: TableAdapterHeightIndexCallback?
|
|
public var selectIndexCallback: TableAdapterSelectIndexCallback?
|
|
public var deleteIndexCallback: TableAdapterDeleteIndexCallback?
|
|
public var didScrollCallback: TableAdapterDidScrollCallback?
|
|
|
|
|
|
public var items: [TableAdapterItem] = []
|
|
|
|
required public init?(coder: NSCoder) {
|
|
super.init(coder: coder)
|
|
update()
|
|
}
|
|
|
|
public override init(frame: CGRect, style: UITableView.Style) {
|
|
super.init(frame: frame, style: style)
|
|
update()
|
|
}
|
|
|
|
open override func draw(_ rect: CGRect) {
|
|
if let color = separatorClr {
|
|
separatorColor = color
|
|
}
|
|
}
|
|
|
|
public func update() {
|
|
delegate = self
|
|
dataSource = self
|
|
|
|
tableFooterView = UIView()
|
|
backgroundColor = .clear
|
|
}
|
|
|
|
public func set(items: [TableAdapterItem], animated: Bool = false, reload: Bool = true) {
|
|
self.clear()
|
|
items.forEach {
|
|
self.unsafeAdd(item: $0)
|
|
// $0.cellHandler?.delegate = self
|
|
}
|
|
if reload { reloadData(animated: animated) }
|
|
}
|
|
|
|
public func clear() {
|
|
items.removeAll()
|
|
}
|
|
|
|
public func reloadData(animated: Bool = false) {
|
|
if animated {
|
|
self.reloadSections(IndexSet(integer: 0), with: .automatic)
|
|
} else {
|
|
self.reloadData()
|
|
}
|
|
}
|
|
|
|
|
|
public func scrollToTop() {
|
|
self.setContentOffset(CGPoint(x: 0, y: 0), animated: true)
|
|
}
|
|
|
|
public func unsafeAdd(item: TableAdapterItem) {
|
|
items.append(item)
|
|
registerNibIfNeeded(for: item)
|
|
}
|
|
|
|
public func registerNibIfNeeded(for item: TableAdapterItem) {
|
|
let nib = UINib(nibName: item.cellReuseIdentifier, bundle: nil)
|
|
self.register(nib, forCellReuseIdentifier: item.cellReuseIdentifier)
|
|
}
|
|
|
|
|
|
private func cellAt(_ indexPath: IndexPath) -> TableAdapterCell? {
|
|
let item = items[indexPath.row]
|
|
let cellIdentifier = item.cellReuseIdentifier
|
|
let cell = self.dequeueReusableCell(withIdentifier: cellIdentifier) as? TableAdapterCell
|
|
cell?.cellData = item.cellData
|
|
return cell
|
|
}
|
|
}
|
|
|
|
// MARK: DataSource
|
|
|
|
extension TableAdapterView: UITableViewDataSource {
|
|
|
|
/// count
|
|
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
|
if !items.isEmpty {
|
|
return items.count
|
|
}
|
|
if let countCallback = countCallback {
|
|
return countCallback()
|
|
}
|
|
return 0
|
|
}
|
|
|
|
/// cell
|
|
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
|
if !items.isEmpty {
|
|
let item = items[indexPath.row]
|
|
let cell = cellAt(indexPath)
|
|
cell?.fill(data: item.cellData)
|
|
return cell ?? UITableViewCell()
|
|
}
|
|
if let cellIndexCallback = cellIndexCallback {
|
|
return cellIndexCallback(indexPath.row)
|
|
}
|
|
return UITableViewCell()
|
|
}
|
|
|
|
|
|
public func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
|
|
if !items.isEmpty {
|
|
let item = items[indexPath.row]
|
|
return item.canEditing()
|
|
}
|
|
return false
|
|
}
|
|
|
|
public func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
|
|
if editingStyle == .delete {
|
|
|
|
items.remove(at: indexPath.row)
|
|
self.beginUpdates()
|
|
self.deleteRows(at: [indexPath], with: .automatic)
|
|
self.endUpdates()
|
|
|
|
deleteIndexCallback?(indexPath.row)
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: Delegate
|
|
|
|
extension TableAdapterView: UITableViewDelegate {
|
|
|
|
/// height
|
|
public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
|
|
if !items.isEmpty {
|
|
return items[indexPath.row].height()
|
|
}
|
|
if let heightIndexCallback = heightIndexCallback {
|
|
return heightIndexCallback(indexPath.row)
|
|
}
|
|
return 0
|
|
}
|
|
|
|
/// select
|
|
public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
|
tableView.deselectRow(at: indexPath, animated: true)
|
|
selectIndexCallback?(indexPath.row)
|
|
}
|
|
|
|
}
|
|
|
|
extension TableAdapterView: UIScrollViewDelegate {
|
|
|
|
public func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
|
didScrollCallback?()
|
|
}
|
|
|
|
|
|
}
|