I have two classes with basically identical tableViewDelegate and tableViewDataSource implementation code. In the interest of leaving the code better than I found it, I figure I should try to reduce duplication. This is proving to be quite difficult. See the example code structure below:
class A : UICollectionViewCell {
//a bunch of code
}
extension A : UITableViewDataSource, UITableViewDelegate {
//A bunch of code that is nearly identical to the other class
}
class B : UIViewController {
//a bunch of code
}
extension B : UITableViewDataSource, UITableViewDelegate {
//A bunch of code that is nearly identical to the other class
}
Both extensions use the same global variables from class A and B respectively. My initial idea was to create a superclass for class A and B that already has these delegates implemented. However, I don't think this will work because classes A and B are not extending the same class. I think I would have to go too far up the class hierarchy to find a superclass that they share.
Is there a good way to reduce this repeated code?
Thanks
You could try to create a shared UITableViewDataSource
and UITableViewDelegate
class that manages the data for both table views. In the example below a ViewModel
that is generic over Item
, can manage lists of Book
or User
instances. They share a CellModel
interface that is used to configure the cell for the table view.
import UIKit
class ViewController: UITableViewController {
struct User: CellModel {
let displayName: String
var title: String { displayName }
}
let viewModel = ViewModel<User>(
items: [
.init(displayName: "Hanna"),
.init(displayName: "Jo")
]
)
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = viewModel
tableView.delegate = viewModel
}
}
// MARK: -
class AnotherViewController: UITableViewController {
struct Book: CellModel {
let title: String
}
let viewModel = ViewModel<Book>(
items: [
.init(title: "Stories from A"),
]
)
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = viewModel
tableView.delegate = viewModel
}
}
// MARK: -
protocol CellModel: Hashable {
var title: String { get }
}
final class ViewModel<Item: CellModel>: NSObject, UITableViewDataSource, UITableViewDelegate {
let items: [Item]
init(items: [Item]) {
self.items = items
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
items.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "CellID") else {
return UITableViewCell(style: .default, reuseIdentifier: "CellID")
}
let item = items[indexPath.row]
var content = cell.defaultContentConfiguration()
content.text = item.title
cell.contentConfiguration = content
return cell
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.