Skip to content

Latest commit

 

History

History
137 lines (92 loc) · 3.9 KB

Memory storage.md

File metadata and controls

137 lines (92 loc) · 3.9 KB

MemoryStorage

MemoryStorage encapsulates storage of data models in memory. It's basically an Array of SectionModel items, which contain array of items for current section.

let storage = MemoryStorage()

Adding items

Adding items to storage creates an update, that may be animated by storage delegate.

// section 0 is implied
storage.addItem(model)

storage.addItem(model, toSection: 0)

// section 0 is implied
storage.addItems([model1,model2])

storage.addItems([model1,model2], toSection:0)

Setting items

Setting items creates an update, that requires storage delegate to reload it's UI. Essentially, it leads to UICollectionView.reloadData or UITableView.reloadData.

// section 0 is implied
storage.setItems([1,2,3])

storage.setItems([4,5,6], forSection: 1)

// 1,2,3 - section 0, 4,5,6 - section 1
storage.setItemsForAllSections([[1,2,3],[4,5,6]])

Insert items

Inserting items creates an update, that may be animated by storage delegate.

try? storage.insertItem(model, to: indexPath)

// Inserts items starting at provided indexPath.
storage.insertItems([1,2,3], at: IndexPath(item: 3, section:0))

// Inserts items at provided indexPaths.
storage.insertItems([1,2], to: [IndexPath(item:3, section: 0), IndexPath(item: 4, section: 0)])

Remove / replace / Reload

Removing / replacing/ reloading items creates an update, that may be animated by storage delegate.

// Items need to conform to `Equatable` protocol
try? storage.removeItem(model)
// Items need to conform to `Equatable` protocol
storage.removeItems([model1,model2])
storage.removeItems(at: indexPaths)

storage.removeItems(fromSection: 1)

// Causes `reloadData`
storage.removeAllItems()

// Item need to conform to `Equatable` protocol
try? storage.replaceItem(model1, with: model2)

// Causes storage update with reload animation, if available
storage.reloadItem(model1)

Moving items

// Animated move
storage.moveItem(at: IndexPath(item:0, section:0), to: IndexPath(item:0, section:1))

// Without animations - useful for datasource only update, such as after drag&drop or reordering, where UI was already updated.
storage.moveItemWithoutAnimation(from: IndexPath(item:0, section:0), to: IndexPath(item:0, section:1))

Managing sections

Deleting / moving / inserting sections creates an update, that may be animated by storage delegate.

storage.deleteSections(IndexSet(integer: 1))

storage.moveSection(1, toSection: 3)

// Reloads data
storage.setSection(SectionModel(), forSection: 1)

// Animated insertion
storage.insertSection(SectionModel(), atIndex: 1)

Batch updates

If you need to perform several animated changes to datasource simultaneously, you can use performUpdates method:

storage.performUpdates {
  storage.addItems([2,4,6])
  try? storage.insertItem(3, to: indexPath(1, 0))
}

Those changes will produce a single StorageUpdate instance, thus allowing UITableView or UICollectionView to animate changes in a single batch update.

Warning. Performing mutually exclusive updates inside block can cause application crash. For example adding and removing the same item may crash UICollectionView.

Retrieving items

let item = storage.item(at: IndexPath(item:1, section:0)

let indexPath = storage.indexPath(forItem:model)

let itemsInSection = storage.items(inSection:0)

let section = storage.section(atIndex:0)

Updating manually

Sometimes you may need to update batch of sections, remove all items, and add new ones. For those massive updates you don't actually need to update interface until update is finished. Wrap your updates in single block and pass it to updateWithoutAnimations method:

storage.updateWithoutAnimations {
    // Add multiple rows, or another batch of edits
}
// Calling reloadData is mandatory after calling this method, or you will get crash at runtime.