Model-Driven UITableView
and UICollectionView
in Swift
IQListKit simplifies working with UITableView
and UICollectionView
by eliminating the need to implement dataSource
methods manually. Just define your sections, models, and cell types — IQListKit takes care of the rest, including:
✅ Automatic diffing and animations
✅ Clean and reusable code
✅ Single API for both UITableView
and UICollectionView
- ✅ Unified API – Works with both
UITableView
andUICollectionView
- ✅ Diffable Data Source – Smooth animations and state updates
- ✅ Declarative Syntax – Cleaner and more concise code
- ✅ Custom Headers/Footers – Easy to implement and manage
- ✅ Reusable Cells – No more
dequeueReusableCell
hassles
Version | Swift | iOS Target | Xcode Version |
---|---|---|---|
IQListKit 1.1.0 | Swift 5.7+ | iOS 9.0+ | Xcode 11+ |
IQListKit 4.0.0+ | Swift 5.7+ | iOS 13.0+ | Xcode 14+ |
IQListKit 5.0.0+ | Swift 5.7+ | iOS 13.0+ | Xcode 14+ |
- Open Xcode → File → Add Package Dependency
- Enter URL:
https://github.com/hackiftekhar/IQListKit.git
- Select the version and install.
Add to your Podfile
:
pod 'IQListKit'
- Clone the repository.
- Drag and drop the
IQListKit
folder into your project.
Let’s build a user list in 5 simple steps!
Make sure your model conforms to Hashable
:
struct User: Hashable {
let id: Int
let name: String
}
Create a cell that conforms to IQModelableCell
:
class UserCell: UITableViewCell, IQModelableCell {
@IBOutlet var nameLabel: UILabel!
struct Model: Hashable {
let user: User
}
var model: Model? {
didSet {
nameLabel.text = model?.user.name
}
}
}
Create a list
in your UIViewController
:
class UsersViewController: UIViewController {
private lazy var list = IQList(listView: tableView, delegateDataSource: self)
private var users = [User(id: 1, name: "John"), User(id: 2, name: "Jane")]
override func viewDidLoad() {
super.viewDidLoad()
loadData()
}
}
Provide data directly to IQListKit
:
func loadData() {
list.reloadData { [users] builder in
let section = IQSection(identifier: "Users")
builder.append([section])
let models: [UserCell.Model] = users.map { .init(user: $0) }
builder.append(UserCell.self, models: models, section: section)
}
}
Handle user selection easily:
extension UsersViewController: IQListViewDelegateDataSource {
func listView(_ listView: IQListView, didSelect item: IQItem, at indexPath: IndexPath) {
if let model = item.model as? UserCell.Model {
print("Selected user: \(model.user.name)")
}
}
}
If you would like to display a single-section list of similar objects in a UITableView
or UICollectionView
, IQListKit provides a convenient IQListWrapper
class to handle all the boilerplate code for you.
You can set up IQListWrapper
in just a few lines of code:
class UsersViewController: UIViewController {
@IBOutlet var tableView: UITableView!
private lazy var listWrapper = IQListWrapper(listView: tableView,
type: UserCell.self,
registerType: .nib,
delegateDataSource: self)
private var users = [User(id: 1, name: "John"), User(id: 2, name: "Jane")]
override func viewDidLoad() {
super.viewDidLoad()
loadData()
}
func loadData() {
listWrapper.setModels(users, animated: true, completion: nil)
}
}
The IQListWrapper
class reduces complexity by handling the setup and data binding automatically, making it ideal for quick implementations!
- Delegate, DataSource and Cell Configuration Guide
- Workaround Guide
- IQListKit Presentation
- Modern Collection View
- Always handle cell reuse correctly to avoid glitches.
- Use lightweight models for better memory usage.
Contributions are welcome!
- Report issues
- Submit pull requests
- Improve documentation
IQListKit is distributed under the MIT license.
Iftekhar Qureshi
- GitHub Sponsors: Support my open-source work
- PayPal: PayPal
- Buy Me a Coffee: Support here
- Twitter: @hackiftekhar
- Website: hackiftekhar.com