CombineCocoa simplifies the connection between UIKit and Combine, allowing seamless binding of UI components to reactive data streams.
- Bind UI elements like
UICollectionView
andUITableView
toPublished
data streams. - Support for custom cell types using Combine.
@Published var items = [String]()
let collectionView = UICollectionView()
private var subscriptions = Set<AnyCancellable>()
collectionView.bind($items, cellType: SomeCell.self) { index, element, cell in
cell.render(model: element)
}.store(in: &subscriptions)
enum CellType {
case regular(DataModel)
case header(String)
}
@Published var cells = [CellType]()
let collectionView = UICollectionView()
private var subscriptions = Set<AnyCancellable>()
collectionView.bind($cells) { collectionView, indexPath, items in
switch items {
case .regular(let data):
return collectionView.dequeueCell(RegularCell.self, indexPath) { cell in
cell.configure(with: data)
}
case .header(let title):
return collectionView.dequeueCell(HeaderCell.self, indexPath) { cell in
cell.setTitle(title)
}
}
}.store(in: &subscriptions)
@Published var tableItems = [String]()
let tableView = UITableView()
private var subscriptions = Set<AnyCancellable>()
tableView.bind($tableItems, cellType: UITableViewCell.self) { index, item, cell in
cell.textLabel?.text = item
}.store(in: &subscriptions)
open class BaseCell<ViewModel>: UITableViewCell {
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
commonInit()
}
public required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
open func commonInit() {
selectionStyle = .none
}
open func render(viewModel: ViewModel) { }
}
final class UserCell: BaseCell<UserViewModel> {
private let nameLabel = UILabel()
override func commonInit() {
super.commonInit()
contentView.addSubview(nameLabel)
}
override func render(viewModel: UserViewModel) {
nameLabel.text = viewModel.name
}
}
final class ProductCell: BaseCell<ProductViewModel> {
private let productLabel = UILabel()
override func commonInit() {
super.commonInit()
contentView.addSubview(productLabel)
}
override func render(viewModel: ProductViewModel) {
productLabel.text = viewModel.title
}
}
@Published var users: [UserViewModel] = []
let tableView = UITableView()
private var subscriptions = Set<AnyCancellable>()
tableView.bind($users, cellType: UserCell.self) { index, user, cell in
cell.render(viewModel: user)
}.store(in: &subscriptions)
Add this to your Package.swift
file:
dependencies: [
.package(url: "https://github.com/KopievDev/CombineCocoa", from: "1.0.0")
]