Skip to content

drewet/DTCollectionViewManager

 
 

Repository files navigation

Build Status   CocoaPod platform   CocoaPod version   License MIT DTCollectionViewManager

This is a sister-project for DTTableViewManager - great tool for UITableView management, built on the same principles.

Try it out!

pod try DTCollectionViewManager

Workflow

Here are 4 simple steps you need to use DTCollectionViewManager:

  1. Your view controller should subclass DTCollectionViewController, and set collectionView property.
  2. You should have subclasses of DTCollectionViewCell.
  3. In your viewDidLoad method, call mapping methods to establish relationship between data models and UICollectionViewCells.
  4. Add data models to memoryStorage, or use CoreData storage class.

API quickstart

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.

Features

DTCollectionViewManager is built on several important concepts, that allow collection view management to be flexible and clean.

Mapping

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.

Datasource and UI synchronization

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.

Custom storage classes

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

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

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 - fixed!

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.

Using storyboards

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.

Foundation class clusters mapping

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

Searching in UICollectionView

DTCollectionViewMemoryStorage

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.

DTCoreDataStorage

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.

Installation

Simplest option is to use CocoaPods:

pod 'DTCollectionViewManager', '~> 2.4'

Requirements

  • iOS 6,7
  • ARC

Documentation

Cocoadocs

Thanks

Thanks to Ash Furrow for his amazing investigative work on UICollectionView updates.

About

Clean and robust UICollectionView management

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors