A declarative type-safe framework for building fast and flexible lists with UITableViews & UICollectionViews
Owl offers a data-driven declarative approach for building fast & flexible list in iOS.
It supports both UICollectionView
& UITableView
; UIStackView
is on the way!
Features Highlights | |
---|---|
🕺 | No more delegates & datasource. Just a fully type-safe declarative content approach |
🧩 | Better architecture to reuse components e decuple data from UI |
🌈 | Animate content changes automatically, no reloadData /performBatchUpdates |
🚀 | Blazing fast diff algorithm based upon DifferenceKit |
🧬 | It uses standard UIKit components at its core. No magic! |
💎 | (COMING SOON) Support for scrollable declarative/fully customizable stack view |
🐦 | Fully made in Swift from Swift ❥ lovers |
Owl was created and maintaned by Daniele Margutti - My home site www.danielemargutti.com.
The preferred installation method is with CocoaPods. Add the following to your Podfile
:
pod 'OwlKit'
Also you can install Owl using Carthage. Add this to your Cartfile
:
github "malcommac/Owl"
Owl is also compatible with SPM (Swift Package Manager) for Swift 5.x+
This is how to achieve a fully functional Contacts list with Owl. It's just a silly example but you can create complex layout with heterogeneous models easily!
director = TableDirector(table: table)
// An adapter encapsulate the logic to render a model (Contact) with a specific ui (ContactCell).
let contactAdapter = TableCellAdapter<Contact,ContactCell> { dr in
// Each adapter exposes all the standard methods of a list, events
// and properties. ctx (context) received from event is a type-safe
// object both for model and cell!
dr.events.dequeue = { ctx in
// element is type-safe, it's the Contact instance!
// cell is type-safe, it's the ContactCell instance
ctx.cell?.item = ctx.element
}
dr.events.didSelect = { ctx in
let vc = ContactDetailVC(people: ctx.element)
navigationController.pushViewController(vc, animated: true)
}
dr.events.shouldHighlight = { ctx in
return ctx.element.isBlacklisted == false
}
}
// Since now our table can show Contact istances using ContactCell
// All events are received only in its adapter.
director?.registerCellAdapter(contactAdapter)
/// Manage your content in a declarative way!
let friendsSection = TableSection(elements: [john,mark,anita])
director?.add(section: friendsSection)
director?.reload()