This is a sister-project for DTTableViewManager - great tool for UITableView management, built on the same principles.
Try it out!
pod try DTCollectionViewManagerHere are 4 simple steps you need to use DTCollectionViewManager:
- Your view controller should subclass
DTCollectionViewController, and set collectionView property. - You should have subclasses of
DTCollectionViewCell. - In your viewDidLoad method, call mapping methods to establish relationship between data models and UICollectionViewCells.
- Add data models to memoryStorage, or use CoreData storage class.
| Key classes | |
|---|---|
| DTCollectionViewController | Your UIViewController, that presents collectionView, needs to subclass* this class. This class implements all UICollectionViewDatasource methods. |
| DTCollectionViewMemoryStorage | Class responsible for holding collectionView models. It is used as a default storage by DTCollectionViewManager. |
| DTCoreDataStorage | Class used to display data, using `NSFetchedResultsController`. |
| DTSectionModel | Object, representing section in UICollectionView. Basically has array of objects and array of supplementary models for current section. |
| Protocols | |
| DTModelTransfer | Protocol, which methods are used to transfer model to UICollectionViewCell subclass, that will be representing it. |
| Convenience classes (optional) | |
| DTCollectionViewCell | UICollectionViewCell subclass, conforming to `DTModelTransfer` protocol. |
| DTCollectionReusableView | UICollectionReusableView subclass, conforming to `DTModelTransfer` protocol. |
DTCollectionViewManager is built on several important concepts, that allow collection view management to be flexible and clean.
Typically, you have UICollectionViewCells, UICollectionReusableViews and your data models, that need to be represented. And every time you need to write method like this:
-(void)configureCell:(UICollectionViewCell *)cell withSomething:(id)something;You'll also will have some NSString reuseIdentifier you will use to dequeue your cells and supplementary views. And you'll also need to register appropriate classes on your UICollectionView instance.
DTCollectionViewManager removes all of that. You will need to call a single method:
[self registerCellClass:[MyCell class] forModelClass:[MyModel class]];or it's supplementary view variant:
[self registerSupplementaryClass:[SupplementaryClass class]
forKind:UICollectionElementKindSectionHeader
forModelClass:[SupplementaryModel class]];And you are done!
So, how does that work? DTCollectionViewManager uses your cell class as a reuseIdentifier for your cell. Every time data model needs to be displayed, it will automatically create UICollectionViewCell and call a method -updateWithModel: on it, which will transfer data model to a cell. Cell is then expected to properly update it's UI, based on data model.
DTCollectionViewManager supports creating cells and supplementary views both from XIBs and storyboards.
Every time you use UICollectionView in your app, you need to think about two things - data models and their representation. For every datasource change there has to be a method, that updates UI. DTCollectionViewManager simplifies that by having methods to update your datasource only. UICollectionView update methods are called automatically. You can also make any changes manually, if you choose to.
DTCollectionViewManager 2.0 introduces support for custom data storage classes. Current storage classes have been extracted to separate project and are used as a dependency. Two data storage classes are supported by default.
Memory storage is basically array of section objects, which contain array of objects and any supplementary models for current section. It is used by default and there's convenience method to retrieve it:
DTCollectionViewMemoryStorage * storage = [self memoryStorage];To add, delete and apply other operations, take a look here: DTMemoryStorage methods
In most cases, adding items to memory storage is as simple as calling:
- (void)addItem:(NSObject *)item;
- (void)addItems:(NSArray *)items toSection:(NSInteger)sectionNumber;Core data storage is a storage class, that is used to interact with NSFetchedResultsController. It's actually extremely easy to use:
NSFetchedResultsController * controller = ...;
self.dataStorage = [DTCoreDataStorage storageWithFetchResultsController:controller];And that's it!
DTCollectionViewManager will display models, based on info that NSFetchedResultsController has. Every update in CoreData database will be properly animated, using info provided by NSFetchedResultsControllerDelegate methods.
UICollectionView has a great API, that provides enourmous possiibilities. Unfortunately, sometimes it is very fragile. It has some iOS 6 issues, some iOS 7 issues, and some issues, that persist in both iOS releases. Most important of them, if of course, insertion of the first item in section.
DTCollectionViewManager tries very hard to eliminate those. And every issue i know of, is fixed in 2.0 release. If something is working not as expected - please open an issue on GitHub. Project also has good unit test coverage, which is very helpful.
To use storyboard collection view, set reuseIdentifier for collection cell or reusable header/footer with the name of your cell, header or footer class. Call registerCellClass:forModelClass: just as for xib registration.
You can also take a look at example, which contains storyboard colllection view with prototyped cell, header, and footer.
Most of the time you will have your own data models for cells. However, sometimes it's more convenient to use Foundation types, such as NSString, NSNumber, etc. For example, if you have supplementary view - header, that does not have any information except for it's title - you'll probably want to use NSString as its model. Mutable versions are also supported.
DTCollectionViewController supports mapping of following Foundation types:
- NSString
- NSNumber
- NSDictionary
- NSArray
Set UISearchBar's delegate property to your DTCollectionViewController subclass.
Call memoryStorage setSearchingBlock:forModelClass: to determine, whether model of passed class should show for current search criteria. This method can be called as many times as you need.
[self.memoryStorage setSearchingBlock:^BOOL(id model, NSString *searchString, NSInteger searchScope, DTSectionModel *section)
{
Example * example = model;
if ([example.text rangeOfString:searchString].location == NSNotFound)
{
return NO;
}
return YES;
} forModelClass:[Example class]];Searching data storage will be created automatically for current search, and it will be used as a datasource for UICollectionView.
DTCollectionViewController will automatically respond to UISearchBar events and update UICollectionView accordingly. Take a look at provided example.
Subclass DTCoreDataStorage and implement single method
- (instancetype)searchingStorageForSearchString:(NSString *)searchString
inSearchScope:(NSInteger)searchScope;You will need to provide a storage with NSFetchedResultsController and appropriate NSPredicate. Model will also need to implement DTModelSearching protocol method, just like with memory storage.
Simplest option is to use CocoaPods:
pod 'DTCollectionViewManager', '~> 2.4'
- iOS 6,7
- ARC
Thanks to Ash Furrow for his amazing investigative work on UICollectionView updates.

