Swiftpack.co - Package - DenTelezhkin/DTCollectionViewManager

CI codecov.io CocoaPod platform CocoaPod version Swift Package Manager compatible Packagist


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

Powerful generic-based UICollectionView management framework, written in Swift.


  • ☑ Powerful mapping system between data models and cells, headers and footers
  • ☑ Support for all Swift types as data models
  • ☑ Support for diffable datasources in iOS 13
  • ☑ Powerful events system, that covers all of UICollectionView delegate and datasource methods
  • ☑ Views created from code, XIB, or storyboard
  • ☑ Flexible Memory/CoreData/Realm.io storage options
  • ☑ Automatic datasource and interface synchronization.
  • ☑ Automatic XIB registration and dequeue
  • ☑ Support for Drag&Drop for iOS 11 and higher
  • ☑ Can be used with UICollectionViewController, or UIViewController with UICollectionView, or any other class, that contains UICollectionView
  • Complete documentation


  • Xcode 9 and higher
  • iOS 8.0 and higher / tvOS 9.0 and higher
  • Swift 4.2 and higher


Swift Package Manager(requires Xcode 11)

Add package into Project settings -> Swift Packages


pod 'DTCollectionViewManager'

Quick start

Let's say you have an array of Posts you want to display in UICollectionView. To quickly show them using DTCollectionViewManager, here's what you need to do:

  • Create UICollectionViewCell subclass, let's say PostCell. Adopt ModelTransfer protocol
class PostCell : UICollectionViewCell, ModelTransfer {
	func update(with model: Post) {
		// Fill your cell with actual data
  • Declare your class as DTCollectionViewManageable, and it will be automatically injected with manager property, that will hold an instance of DTCollectionViewManager.

  • Make sure your UICollectionView outlet is wired to your class and call registration methods (typically in viewDidLoad method):

class PostsViewController: UIViewController, DTCollectionViewManageable {

    @IBOutlet weak var collectionView: UICollectionView!

    override func viewDidLoad() {

ModelType will be automatically gathered from your PostCell. If you have a PostCell.xib file, it will be automatically registered for PostCell. If you have a storyboard with PostCell, set it's reuseIdentifier to be identical to class - "PostCell".

  • Add your posts!

That's it! It's that easy!


Mapping and registration


  • register(_:)
  • registerNibNamed(_:for:)
  • registerNibless(_:)

Headers and footers:

  • registerHeader(_:)
  • registerNibNamed(_:forHeader:)
  • registerNiblessHeader(_:)
  • registerFooter(_:)
  • registerNibNamed(_:forFooter:)
  • registerNiblessFooter(_:)


  • registerSupplementary(_:forKind:)
  • registerNibNamed(_:forSupplementary:ofKind:)
  • registerNiblessSupplementary(_:forKind:)

Data models

DTCollectionViewManager supports all Swift and Objective-C types as data models. This also includes protocols and subclasses.

protocol Food {}
class Apple : Food {}
class Carrot: Food {}

class FoodCollectionViewCell : UICollectionViewCell, ModelTransfer {
    func update(with model: Food) {
        // Display food in a cell

Storage classes

DTModelStorage is a framework, that provides storage classes for DTCollectionViewManager. By default, storage property on DTCollectionViewManager holds a MemoryStorage instance.


MemoryStorage is a class, that manages UICollectionView models in memory. It has methods for adding, removing, replacing, reordering models etc. You can read all about them in DTModelStorage repo. Basically, every section in MemoryStorage is an array of SectionModel objects, which itself is an object, that contains an array of items.


CoreDataStorage is meant to be used with NSFetchedResultsController. It automatically monitors all NSFetchedResultsControllerDelegate methods and updates UI accordingly to it's changes. All you need to do to display CoreData models in your UICollectionView, is create CoreDataStorage object and set it on your storage property of DTCollectionViewManager.

It also recommended to use built-in CoreData updater to properly update UICollectionView:

manager.collectionViewUpdater = manager.coreDataUpdater()

Standard flow for creating CoreDataStorage can be something like this:

let request = NSFetchRequest<Post>()
request.entity = NSEntityDescription.entity(forEntityName: String(Post.self), in: context)
request.fetchBatchSize = 20
request.sortDescriptors = [NSSortDescriptor(key: "id", ascending: true)]
let fetchResultsController = NSFetchedResultsController(fetchRequest: request, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
_ = try? fetchResultsController.performFetch()

manager.storage = CoreDataStorage(fetchedResultsController: fetchResultsController)

Keep in mind, that MemoryStorage is not limited to objects in memory. For example, if you have CoreData database, and you now for sure, that number of items is not big, you can choose not to use CoreDataStorage and NSFetchedResultsController. You can fetch all required models, and store them in MemoryStorage.


RealmStorage is a class, that is meant to be used with realm.io databases. To use RealmStorage with DTCollectionViewManager, add following line to your Podfile:

    pod 'DTModelStorage/Realm'

If you are using Carthage, RealmStorage will be automatically built along with DTModelStorage.

Diffable datasources in iOS 13

Diffable datasources is a cool new feature, that is introduced in UIKit in iOS / tvOS 13. DTCollectionViewManager provides a powerful integration layer with it, but in order to understand how this layer works, it's highly recommended to check out great Advances in UI Data Sources WWDC session.

If you don't use DTCollectionViewManager, you would typically create diffable datasource like so (taken from Apple's sample code on diffable datasources):

dataSource = UICollectionViewDiffableDataSource
    <Section, MountainsController.Mountain>(collectionView: mountainsCollectionView) {
        (collectionView: UICollectionView, indexPath: IndexPath,
        mountain: MountainsController.Mountain) -> UICollectionViewCell? in
    guard let mountainCell = collectionView.dequeueReusableCell(
        withReuseIdentifier: LabelCell.reuseIdentifier, for: indexPath) as? LabelCell else {
            fatalError("Cannot create new cell") }
    mountainCell.label.text = mountain.name
    return mountainCell

One of DTCollectionViewManagers main goals is to get rid of String identifiers, and to handle cell creation, as well as updating cell with it's model, for you. Which is why with DTCollectionViewManager code, equivalent to one above, is the following:

dataSource = manager.configureDiffableDataSource { indexPath, model in
    return model

You should persist strong reference to dataSource object, and use it for constructing sections and items exactly as described in Apple documentation and WWDC session.

Diffable datasources and DTCollectionViewManager 7 are tightly integrated, so all events, even datasource ones like manager.configure(_:), continue to work in the same way as they were working before.

Events integration is possible, because DTCollectionViewManager injects a special ProxyDiffableDataSourceStorage object between UICollectionViewDiffableDataSource and UICollectionView. This storage does not store data models and just queries diffable data source to receive them. It does, however, implement section supplementary model providers.

DTCollectionViewManager supports both generic UICollectionViewDiffableDataSource<SectionType,ItemType> and non-generic UICollectionViewDiffableDataSourceReference with the same method name(configureDiffableDataSource). Resulting diffable datasource type is inferred from your declaration of the datasource.

Note Due to underlying implementation details, using UICollectionViewDiffableDataSource.supplementaryViewProvider property is not supported. Please use ProxyDiffableDataSourceStorage.supplementaryModelProvider property instead:


Keep in mind, that for diffable datasources, collectionViewUpdater property will contain nil, since UI updates are handled by diffable datasource itself.

Reacting to events

Event system in DTCollectionViewManager 5 allows you to react to UICollectionViewDelegate, UICollectionViewDataSource and UICollectionViewDelegateFlowLayout events based on view and model types, completely bypassing any switches or ifs when working with UICollectionView API. For example:

manager.didSelect(PostCell.self) { cell,model,indexPath in
  print("Selected PostCell with \(model) at \(indexPath)")


While it's possible to register multiple closures for a single event, only first closure will be called once event is fired. This means that if the same event has two closures for the same view/model type, last one will be ignored. You can still register multiple event handlers for a single event and different view/model types. You can see how reactions are being searched for in DTModelStorage EventReaction extension.

Event types

There are two types of events:

  1. Event where we have underlying view at runtime
  2. Event where we have only data model, because view has not been created yet.

In the first case, we are able to check view and model types, and pass them into closure. In the second case, however, if there's no view, we can't make any guarantees of which type it will be, therefore it loses view generic type and is not passed to closure. These two types of events have different signature, for example:

// Signature for didSelect event
// We do have a cell, when UICollectionView calls "collectionView(_:didSelectItemAt:)" method
open func didSelect<T:ModelTransfer>(_ cellClass:  T.Type, _ closure: @escaping (T,T.ModelType, IndexPath) -> Void) where T:UICollectionViewCell

// Signature for sizeForCell(withItem:) event
// When UICollectionView calls "collectionView(_:layout:sizeForItemAt:)" method, cell is not created yet, so closure contains two arguments instead of three, and there are no guarantees made about cell type, only model type
open func sizeForCell<T>(withItem itemType: T.Type, _ closure: @escaping (T, IndexPath) -> CGFloat)

It's also important to understand, that event system is implemented using responds(to:) method override and is working on the following rules:

  • If DTCollectionViewManageable is implementing delegate method, responds(to:) returns true
  • If DTCollectionViewManager has events tied to selector being called, responds(to:) also returns true

What this approach allows us to do, is configuring UICollectionView knowledge about what delegate method is implemented and what is not. For example, DTCollectionViewManager is implementing collectionView(_:layout:sizeForItemAt:) method, however if you don't call sizeForCell(withItem:_:) method, you are safe to use self-sizing cells in UICollectionView. While a lot of delegate methods are implemented, only those that have events or are implemented by delegate will be called by UICollectionView.

DTCollectionViewManager has the same approach for handling each delegate and datasource method:

  • Try to execute event, if cell and model type satisfy requirements
  • Try to call delegate or datasource method on DTCollectionViewManageable instance
  • If two previous scenarios fail, fallback to whatever default UICollectionView has for this delegate or datasource method

Events configuration

To have compile safety when registering events, you can use configureEvents method:

manager.configureEvents(for: IntCell.self) { cellType, modelType in
  manager.estimatedHeight(for: modelType) { _,_ in
    return 44

Advanced usage

Drag and Drop in iOS 11

There is a dedicated repo, containing Apple's sample on Drag&Drop, enhanced with DTTableViewManager and DTCollectionViewManager. Most of the stuff is just usual drop and drag delegate events, but there is also special support for UITableView and UICollectionView placeholders, that makes sure calls are dispatched to main thread, and if you use MemoryStorage, performs datasource updates automatically.

Reacting to content updates

Sometimes it's convenient to know, when data is updated, for example to hide UICollectionView, if there's no data. CollectionViewUpdater has willUpdateContent and didUpdateContent properties, that can help:

updater.willUpdateContent = { update in
  print("UI update is about to begin")

updater.didUpdateContent = { update in
  print("UI update finished")

Customizing UICollectionView updates

DTCollectionViewManager uses CollectionViewUpdater class by default. However for CoreData you might want to tweak UI updating code. For example, when reloading cell, you might want animation to occur, or you might want to silently update your cell. This is actually how Apple's guide for NSFetchedResultsController suggests you should do. Another interesting thing it suggests that .Move event reported by NSFetchedResultsController should be animated not as a move, but as deletion of old index path and insertion of new one.

If you want to work with CoreData and NSFetchedResultsController, just call:

manager.collectionViewUpdater = manager.coreDataUpdater()

CollectionViewUpdater constructor allows customizing it's basic behaviour:

let updater = CollectionViewUpdater(collectionView: collectionView, reloadRow: { indexPath in
  // Reload row
}, animateMoveAsDeleteAndInsert: false)

These are all default options, however you might implement your own implementation of CollectionViewUpdater, the only requirement is that object needs to conform to StorageUpdating protocol. This gives you full control on how and when DTCollectionViewManager will update UICollectionView.

Conditional mappings

There can be cases, where you might want to customize mappings based on some criteria. For example, you might want to display model in several kinds of cells for different sections:

class FoodTextCell: UICollectionViewCell, ModelTransfer {
    func update(with model: Food) {
        // Text representation

class FoodImageCell: UICollectionViewCell, ModelTransfer {
    func update(with model: Food) {
        // Photo representation

manager.register(FoodTextCell.self) { mapping in mapping.condition = .section(0) }
manager.register(FoodImageCell.self) { mapping in mapping.condition = .section(1) }

Or you may implement completely custom conditions:

manager.register(FooCell.self) { mapping in
  mapping.condition = .custom({ indexPath, model in
    guard let model = model as? Int else { return false }
    return model > 2

You can also change reuseIdentifier to be used:

manager.register(NibCell.self) { mapping in
    mapping.condition = .section(0)
    mapping.reuseIdentifier = "NibCell One"
controller.manager.registerNibNamed("CustomNibCell", for: NibCell.self) { mapping in
    mapping.condition = .section(1)
    mapping.reuseIdentifier = "NibCell Two"

Anomaly handler

DTCollectionViewManager is built on some conventions. For example, your cell needs to have reuseIdentifier that matches the name of your class, XIB files need to be named also identical to the name of your class(to work with default mapping without customization). However when those conventions are not followed, or something unexpected happens, your app may crash or behave inconsistently. Most of the errors are reported by UICollectionView API, but there's space to improve.

DTTableViewManager as well as DTCollectionViewManager and DTModelStorage now have dedicated anomaly analyzers, that try to find inconsistencies and programmer errors when using those frameworks. They detect stuff like missing mappings, inconsistencies in xib files, and even unused events. By default, detected anomalies will be printed in console while you are debugging your app. For example, if you try to register an empty xib to use for your cell, here's what you'll see in console:

⚠️[DTCollectionViewManager] Attempted to register xib EmptyXib for PostCell, but this xib does not contain any views.

Messages are prefixed, so for DTTableViewManager messages will have [DTTableViewManager] prefix.

By default, anomaly handler only prints information into console and does not do anything beyond that, but you can change it's behavior by assigning a custom handler for anomalies:

manager.anomalyHandler.anomalyAction = { anomaly in
  // invoke custom action

For example, you may want to send all detected anomalies to analytics you have in your app. For this case anomalies implement shorter description, that is more suitable for analytics, that often have limits for amount of data you can put in. To do that globally for all instances of DTCollectionViewManager that will be created during runtime of your app, set default action:

DTCollectionViewManagerAnomalyHandler.defaultAction = { anomaly in

  analytics.postEvent("DTCollectionViewManager", anomaly.description)

If you use DTTableViewManager and DTCollectionViewManager, you can override 3 default actions for both manager frameworks and DTModelStorage, presumably during app initialization, before any views are loaded:

DTTableViewManagerAnomalyHandler.defaultAction = { anomaly in }
DTCollectionViewManagerAnomalyHandler.defaultAction = { anomaly in }
MemoryStorageAnomalyHandler.defaultAction = { anomaly in }

Unregistering mappings

You can unregister cells, headers and footers from DTCollectionViewManager and UICollectionView by calling:

manager.unregisterSupplementary(SupplementaryView.self, forKind: "foo")

This is equivalent to calling collection view register methods with nil class or nil nib.


  • Alexey Belkevich for providing initial implementation of CellFactory.
  • Michael Fey for providing insight into NSFetchedResultsController updates done right.
  • Nickolay Sheika for great feedback, that helped shaping 3.0 release.
  • Artem Antihevich for great discussions about Swift generics and type capturing.


Stars: 292


Used By

Total: 0


7.2.0 - 2020-07-02 09:46:52


  • Deployment targets - iOS 11 / tvOS 11.
  • Minimum Swift version required: 5.0
  • Added support for DTModelStorage/Realm with Realm 5

Please note, that this framework version source is identical to previous version, which supports iOS 8 / tvOS 9 / Swift 4.2 and higher.

7.1.0 - 2020-04-29 11:55:34


  • It's not longer necessary to import DTModelStorage framework to use it's API's. import DTCollectionViewManager now implicitly exports DTModelStorage as well.

7.0.0 - 2019-11-08 12:15:54

  • willCommitMenuWithAnimator method has been made unavailable for Xcode 11.2, because UICollectionViewDelegate method it used has been removed from UIKit on Xcode 11.2.

7.0.0-beta.2 - 2019-09-06 09:44:46

  • Added support for Xcode versions, that are older than Xcode 11.

7.0.0-beta.1 - 2019-08-20 10:58:42

This is a major release with some breaking changes, please read DTCollectionViewManager 7.0 Migration Guide


  • DTCollectionViewManager now requires to be built with Swift 4.2 and later.
  • Anomaly event verification now allows subclasses to prevent false-positives.
  • animateChangesOffScreen property on CollectionViewUpdater that allows to turn off animated updates for UICollectionView when it is not on screen.


  • configureDiffableDataSource(modelProvider:) method to enable UICollectionViewDiffableDataSource with DTCollectionViewManager.
  • DTCollectionViewManager.supplementaryStorage getter, that conditionally casts current storage to SupplementaryStorage protocol.
  • Ability to customize bundle, from which xib files are loaded from by setting bundle property on ViewModelMapping in mappingBlock. As before, bundle defaults to Bundle(for: ViewClass.self).

New method wrappers for iOS 13 API

  • shouldBeginMultipleSelectionInteraction
  • didBeginMultipleSelectionInteraction
  • didEndMultipleSelectionInteraction
  • contextMenuConfiguration(for:)
  • previewForHighlightingContextMenu
  • previewForDismissingContextMenu
  • willCommitMenuWithAnimator


  • Usage of previously deprecated and now removed from DTModelStorage ViewModelMappingCustomizing protocol.


DTModelStorage header, footer and supplementary model handling has been largely restructured to be a single closure-based API. Read more about changes in DTModelStorage changelog. As a result of those changes, several breaking changes in DTCollectionViewManager include:

  • SectionModel extension with collectionHeaderModel and collectionFooterModel properties has been removed.
  • Because headers/footers are now a closure based API, setSectionHeaderModels and setSectionFooterModels do not create sections by default, and do not call collectionView.reloadData.

Other breaking changes:

  • collectionViewUpdater will contain nil if DTCollectionViewManager is configured to work with UICollectionViewDiffableDataSource.
  • DTCollectionViewNonOptionalManageable protocol was removed and replaced by collectionView property on DTCollectionViewManageable protocol. One of collectionView/optionalCollectionView properties must be implemented by DTCollectionViewManageable instance to work with DTCollectionViewManager.
  • collectionView property in DTCollectionViewManageable protocol is now ImplicitlyUnwrappedOptional instead of Optional. This change is done to unify API with UICollectionViewController change and DTTableViewManager API for consistency.

WARNING Because of default implementations for new property this will not show as a compile error, instead crashing in runtime. Please make sure to update all definitions of

var collectionView: UICollectionView?


var collectionView: UICollectionView!.

If you need optional collection view, use optionalCollectionView property instead.


Following methods have been deprecated due to their delegate methods being deprecated in iOS 13:

  • shouldShowMenuForItemAt
  • canPerformAction
  • performAction

6.6.0 - 2019-06-17 20:25:48

  • Added support for Swift Package Manager in Xcode 11

6.5.0 - 2019-04-07 11:58:08


  • Convenience constructor for DTCollectionViewManager object: init(storage:) that allows to create it's instance without initializing MemoryStorage.
  • Static variable defaultStorage on DTCollectionViewManager that allows to configure which Storage class is used by default.
  • Documentation
  • Support for Xcode 10.2 and Swift 5


  • Support for Xcode 9 and Swift 3

6.4.2 - 2019-02-05 10:51:27

  • move(:_,:_) method was deprecated and no longer works due to a logic bug, that can prevent this method from being called if sourceIndexPath is off screen when this event was called by UICollectionView. Please use new method moveItemAtTo(:_) to subscribe to move events in the datasource.

6.4.1 - 2018-10-30 11:14:39

  • Fix infinite recursion bug with UICollectionView.canFocusItemAt(:) method(thanks, @skydivedan!)

6.4.0 - 2018-09-25 14:37:45

  • Support for Xcode 10 and Swift 4.2

6.3.0 - 2018-06-09 13:06:15


  • Anomaly-detecting and reporting system for DTCollectionViewManager. Read more about it in Anomaly Handler Readme section. Anomaly handler system requires Swift 4.1 and higher.
  • Support for Swift 4.2 in Xcode 10 (beta 1).


  • Calling startManaging(withDelegate:_) method is no longer required.


  • viewFactoryErrorHandler property on DTCollectionViewManager was removed, all supported errors and warnings are now a part of anomaly reporting system

6.1.1 - 2018-04-02 15:10:40

6.1.0 - 2018-01-19 16:09:11

6.1.0-beta.1 - 2017-12-04 12:43:46

  • Implemented new system for deferring datasource updates until performBatchUpdates block. This system is intended to fight crash, that might happen when performBatchUpdates method is called after UITableView.reloadData method(for example after calling memoryStorage.setItems, and then immediately memoryStorage.addItems). This issue is detailed in https://github.com/DenHeadless/DTCollectionViewManager/issues/27 and https://github.com/DenHeadless/DTCollectionViewManager/issues/23. This crash can also happen, if iOS 11 API UITableView.performBatchUpdates is used. This system is turned on by default. If, for some reason, you want to disable it and have old behavior, call:
manager.memoryStorage.defersDatasourceUpdates = false

Please note, though, that new default behavior is recommended, because it is more stable and works the same on both UITableView and UICollectionView.

  • collectionViewUpdater property on DTCollectionViewManager is now of CollectionViewUpdater type instead of opaque StorageUpdating type. This should ease use of this object and prevent type unneccessary type casts.

6.0.0 - 2017-11-01 13:28:39

  • Updated for Xcode 9.1 / Swift 4.0.2

6.0.0-beta.3 - 2017-10-05 15:36:02

  • Makes DTCollectionViewManager property weak instead of unowned to prevent iOS 10-specific memory issues/crashes.

6.0.0-beta.2 - 2017-09-27 15:31:23

  • Build with Xcode 9.0 final release.
  • Fixed partial-availability warnings.

6.0.0-beta.1 - 2017-09-10 18:01:55

This is a major release with some breaking changes, please read DTTableViewManager 6.0 Migration Guide

  • Added updateVisibleCells(_:) method, that allows updating cell data for visible cells with callback on each cell. This is more efficient than calling reloadData when number of elements in UICollectionView does not change, and only contents of items change.
  • Implement configureEvents(for:_:) method, that allows batching in several cell events to avoid using T.ModelType for events, that do not have cell created.
  • Added DTCollectionViewDropPlaceholderContext wrapper with convenience support for UICollectionView placeholders.
  • Implemented UICollectionViewDragDelegate and UICollectionViewDropDelegate events.
  • Added 10 more UICollectionViewDelegate and UICollectionViewDelegateFlowLayout events.
  • Added missing events for UICollectionViewDatasource protocol: collectionView:moveItemAt:to:, indexTitlesFor:, collectionView:indexPathForIndexTitle:at:
  • Implemented conditional mappings
  • UICollectionViewDelegate and UICollectionViewDatasource implementations have been refactored from DTCollectionViewManager to DTCollectionViewDelegate and DTCollectionViewDataSource classes.
  • Added DTCollectionViewNonOptionalManageable protocol, that can be used with non-optional UICollectionView properties on your managed instance.

5.3.1 - 2017-06-29 12:20:38

  • Initial support for Swift 3.2 (Xcode 9 beta-1).
  • Fixed registerNiblessHeader and registerNiblessFooter to properly call nibless supplementary methods.

5.3.0 - 2017-04-06 15:14:32

  • Use new events system from DTModelStorage, that allows events to be properly called for cells, that are created using ViewModelMappingCustomizing protocol.

5.2.0 - 2017-01-29 09:25:28

  • Setting CollectionViewUpdater instance to collectionViewUpdater property on DTCollectionViewManager now triggers didUpdateContent closure on CollectionViewUpdater.

5.1.0 - 2016-10-28 15:08:32

Dependency changelog -> DTModelStorage 4.0.0 and higher

  • CollectionViewUpdater has been rewritten to use new StorageUpdate properties that track changes in order of their occurence.
  • CollectionViewUpdater reloadItemClosure and DTCollectionViewManager updateCellClosure now accept indexPath and model instead of just indexPath. This is done because update may happen after insertions and deletions and object that needs to be updated may exist on different indexPath.

5.0.0 - 2016-10-23 13:34:19

No changes

5.0.0-beta.3 - 2016-10-13 11:13:35

  • DTModelStorage/Realm dependency now requires Realm 2.0

5.0.0-beta.2 - 2016-09-24 10:06:59

  • Enables RealmStorage from DTModelStorage dependency.

5.0.0-beta.1 - 2016-09-17 09:44:55

This is a major release, written in Swift 3. Read [Migration guide](Documentation/DTCollectionViewManager 5 migration guide.md) with descriptions of all features and changes.

Dependency changelog -> DTModelStorage 3.0.0 and higher


  • New events system that covers almost all available UICollectionViewDelegate, UICollectionViewDataSource and UICollectionViewDelegateFlowLayout delegate methods.
  • New class - CollectionViewUpdater, that is calling all animation methods for UICollectionView when required by underlying storage.
  • updateCellClosure method on DTCollectionViewManager, that manually updates visible cell instead of calling collectionView.reloadItemsAt(_:) method.
  • coreDataUpdater property on DTCollectionViewManager, that creates CollectionViewUpdater object, that follows Apple's guide for updating UICollectionView from NSFetchedResultsControllerDelegate events.
  • isManagingCollectionView property on DTCollectionViewManager.
  • unregisterCellClass(_:), unregisterHeaderClass(_:), unregisterFooterClass(_:), unregisterSupplementaryClass(_:forKind:) methods to unregister mappings from DTCollectionViewManager and UICollectionView


  • Swift 3 API Design guidelines have been applied to all public API.
  • Event system is migrated to new EventReaction class from DTModelStorage
  • Now all view registration methods use NSBundle(forClass:) constructor, instead of falling back on DTCollectionViewManager viewBundle property. This allows having cells from separate bundles or frameworks to be used with single DTCollectionViewManager instance.


  • viewBundle property on DTCollectionViewManager
  • itemForVisibleCell, itemForCellClass:atIndexPath:, itemForHeaderClass:atSectionIndex:, itemForFooterClass:atSectionIndex: were removed - they were not particularly useful and can be replaced with much shorter Swift conditional typecasts.
  • All events methods with method pointer semantics. Please use block based methods instead.
  • registerCellClass:whenSelected method, that was tightly coupling something that did not need coupling.

4.8.0 - 2016-09-10 12:12:42


  • Now all view registration methods use NSBundle(forClass:) constructor, instead of falling back on DTCollectionViewManager viewBundle property. This allows having cells from separate bundles or frameworks to be used with single DTCollectionViewManager instance.


  • viewBundle property on DTCollectionViewManager

4.7.0 - 2016-05-24 15:38:49

Dependency changelog -> DTModelStorage 2.6.0 and higher

4.6.0 - 2016-04-27 11:51:20

Dependency changelog -> DTModelStorage 2.5 and higher


  • Update to Swift 2.2. This release is not backwards compatible with Swift 2.1.


  • Require Only-App-Extension-Safe API is set to YES in framework targets.

4.5.2 - 2016-01-10 10:47:27


  • Fixed a bug, where supplementary views from storyboards did not have their outlets properly initialized(@RenGate, #16)