TestsTested | ✓ |
LangLanguage | Objective C++Objective C++ |
License | MIT |
ReleasedLast Release | Aug 2016 |
Maintained by Jonathan Crooke.
A set of helpers and features for working with Facebook ComponentKit. This library, when installed via CocoaPods, is modular. It currently has the following modules:
ComponentKit provides CKCollectionViewTransactionalDataSource
as a CKTransactionalComponentDataSource
interface for UICollectionView
. CKTableViewTransactionalDataSource
provides the same, but for UITableView
, albeit with a few necessary and useful differences and additions.
Yes, and no. UICollectionView
provides a great deal of flexibility, but a lot less out-of-the-box. UITableView
's strength is its familiar and user friendly native features, such as:
All these are possible with UICollectionView
, but the implementations are up to you.
The basic implementation of CKTableViewTransactionalDataSource
is quite trivial, however additional API is necessary in order to expose the full power of UITableView
.
UICollectionView
delegates quite a lot of its power to its layout object. This is useful for ComponentKit, since we can do most customisation relating to animations, etc., through an entirely separate main thread object that needn't be touched by CK. Not so for UITableView
, though. For example, native animations must be specified when the rows and sections are added/removed/updated/deleted inside the -beginUpdates
, -endUpdates
transaction. In order to expose these features, CKToolbox
provides CKTableViewTransactionalDataSourceCellConfiguration
, a simple value object that can configure:
A default configuration can be passed to the initializer, and override configurations provided in the userInfo
dictionary argument with the CKTableViewTransactionalDataSourceCellConfigurationKey
or one of the cellConfiguration
argument methods can be used.
The expected usage pattern is:
-[CKTableViewTransactionalDataSource cellConfiguration]
, which always returns a copy), mutate any properties that you wish to override for an update operation. Pass this object in the data source update. It will override the default configuration for that operation only.A good example of this pattern is used in the provided demo app: since the data source uses a -beginUpdates
/-endUpdates
transaction to enqueue all changes, there will be animations when the initial content is inserted. Perhaps we don't want that, would like to see the initial content appear immediately, but would like animations in all later updates. In that case:
-animationsDisabled
property and use this configuration to override the default for this operation only.Both UICollectionView
and UITableView
share very similar APIs. As such,
CKTableViewTransactionalDataSource
actually implements CKTransactionalDataSourceInterface
, which abstracts the most essential parts of CKCollectionViewTransactionalDataSource
's interface. Therefore, should you wish to implement some architecture that is agnostic of the eventual output view of a component-based collection, you could provide an interface of type id <CKTransactionalDataSourceInterface>
. This way, other than instantiation, all collection operations are essentially the same.
A demo app is provided, a simple reference app with a list of endangered animals from the WWF Species Directory. Swipe the cells to reveal additional features.
UITableView
's non-primary features are only roughly supported in the initial version. There may be a lot missingupdateConfiguration:mode:...
) seems a little unsatisfactory at the momentCKTableViewTransactionalDataSourceCellConfiguration
, but for now can also be supported in UITableViewDelegate
methods. For example, the demo app uses -tableView:willDisplayCell:forRowAtIndexPath:
.CKCollectionViewDataSourceChangesetBuilder is a DSL builder for ComponentKit's CKTransactionalComponentDataSourceChangeset
. It is heavily inspired by Masonry, and should allow you to write very readable code for building your changesets.
CKCollectionViewDataSourceChangesetBuilder
uses verbs, nouns and prepositions in order to allow you to express your changeset builds in readable English, with just a few exceptions. A few examples will make this clearer:
[CKCollectionViewDataSourceChangesetBuilder build:^(CKCollectionViewDataSourceChangesetBuilder *builder) {
builder.insert.section.at.index(0);
builder.insert.item(@"Foo").at.indexPath([NSIndexPath indexPathForItem:1 inSection:4]);
builder.remove.section.at.index(1);
builder.move.section.at.index(0).to.index(4);
}];
Due to the limited number of keywords, the possible combinations should hopefully be fairly self-explanatory. The builder has been written to throw useful exceptions when the syntax is misused.
CKCollectionViewDataSourceChangesetBuilderTests
provides examples of all of the syntax combinations, so please take a look there first.
ck_indexPath(ITEM, SECTION)
saves constant use of [NSIndexPath indexPathForItem:inSection:]
.The following two macros aim to compensate for the lack of default arguments in Objective-C; when moving or removing items we need to reuse the verb item
. However, since we have no object to insert the argument must be nil
. This wouldn't be nearly as readable. Instead you can use:
ck_removeItem
instead of remove.item(nil)
.ck_moveItem
instead of move.item(nil)
.ComponentKit
is written primarily in Obj-C++, which means you will usually be using it from within Obj-C++ contexts. Whilst it's possible you could create changesets from Swift contexts, I don't believe this is enough to justify another implementation at this time. Of course, if someone would like to implement it then I'll be happy to receive a PR!
ComponentKit directly supports inserting content, and explicitly deleting items and sections, but does not directly support easily wiping the data source's complete content. The CKTransactionalComponentDataSourceRemoveAll
provides the method - (CKTransactionalComponentDataSourceChangeset*)removeAllChangeset
which returns a change set that can be used to remove all items and sections currently present in the data source. Implementations are provided for CKTransactionalComponentDataSourceState
and CKCollectionViewTransactionalDataSource
. Additionally, CKTableViewTransactionalDataSource implements this protocol.
RemoveAll
module merged into the new "Core" module. This makes features considerably more convenient to use.