Skip to content
This repository was archived by the owner on Jun 24, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
231 changes: 231 additions & 0 deletions content/notes/wwdc20/10045.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
---
contributors: dasauto
---
# Sample Code
Download the [sample code](https://developer.apple.com/documentation/uikit/views_and_controls/collection_views/implementing_modern_collection_views) to learn more about Modern Collection Views.

# Diffable Data Source
## Recap

* Introduced in iOS 13.
* Simplifies UI State.
* Automatic animations.
* No more batch updates.
* More to watch session [220](https://developer.apple.com/videos/play/wwdc2019/220) from WWDC 19: Advances in UI Data Sources.

## [Section Snapshots](https://developer.apple.com/documentation/uikit/nsdiffabledatasourcesectionsnapshot)
* It encapsulates the data for a single section in a UICollectionView.
* Allow data sources to be more composable into section-sized chunks of data. (It's able to present same data use different layout in different sections.)
* Allow modeling of hierarchical data, which is needed to support rendering outline-style UIs.

### Examples
![][section_snapshots]

* Top: Horizontally scrolling section.
* Middle: Outline style section.
* Bottom: List section.

It composes Diffable Data Source from three distinct section snapshots each representing a single section's content.

### APIs
```swift
// NSDiffableDataSourceSectionSnapshot

@available(iOS 14.0, tvOS 14.0, *)
public struct NSDiffableDataSourceSectionSnapshot<ItemIdentifierType> where ItemIdentifierType : Hashable {

public init()

public init(_ snapshot: NSDiffableDataSourceSectionSnapshot<ItemIdentifierType>)

public mutating func append(_ items: [ItemIdentifierType], to parent: ItemIdentifierType? = nil)

public mutating func insert(_ items: [ItemIdentifierType], before item: ItemIdentifierType)

public mutating func insert(_ items: [ItemIdentifierType], after item: ItemIdentifierType)

public mutating func delete(_ items: [ItemIdentifierType])

public mutating func deleteAll()

public mutating func expand(_ items: [ItemIdentifierType])

public mutating func collapse(_ items: [ItemIdentifierType])

public mutating func replace(childrenOf parent: ItemIdentifierType, using snapshot: NSDiffableDataSourceSectionSnapshot<ItemIdentifierType>)

public mutating func insert(_ snapshot: NSDiffableDataSourceSectionSnapshot<ItemIdentifierType>, before item: (ItemIdentifierType))

public mutating func insert(_ snapshot: NSDiffableDataSourceSectionSnapshot<ItemIdentifierType>, after item: (ItemIdentifierType))

public func isExpanded(_ item: ItemIdentifierType) -> Bool

public func isVisible(_ item: ItemIdentifierType) -> Bool

public func contains(_ item: ItemIdentifierType) -> Bool

public func level(of item: ItemIdentifierType) -> Int

public func index(of item: ItemIdentifierType) -> Int?

public func parent(of child: ItemIdentifierType) -> ItemIdentifierType?

public func snapshot(of parent: ItemIdentifierType, includingParent: Bool = false) -> NSDiffableDataSourceSectionSnapshot<ItemIdentifierType>

public var items: [ItemIdentifierType] { get }

public var rootItems: [ItemIdentifierType] { get }

public var visibleItems: [ItemIdentifierType] { get }
}
```
* Use `append` API to add content to section snapshot.
* The optional parent parameter allows us to create parent-child relationships in the section snapshot.

```swift
// UICollectionViewDiffableDataSource additions for iOS 14

extension UICollectionViewDiffableDataSource<Item, Section> {

func apply(_ snapshot: NSDiffableDataSourceSectionSnapshot<Item>,
to section: Section,
animatingDifferences: Bool = true,
completion: (() -> Void)? = nil)

func snapshot(for section: Section) ->
NSDiffableDataSourceSectionSnapshot<Item>
}
```
Code example:

```swift
// Example of using snapshots and section snapshots together

func update(animated: Bool=true) {

// Add our sections in a specific order
let sections: [Section] = [.recent, .top, .suggested]
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
snapshot.appendSections(sections)
dataSource.apply(snapshot, animatingDifferences: animated)

// update each section's data via section snapshots in the existing position
for section in sections {
let sectionItems = items(for: section)
var sectionSnapshot = NSDiffableDataSourceSectionSnapshot<Item>()
sectionSnapshot.append(sectionItems)
dataSource.apply(sectionSnapshot, to: section, animatingDifferences:animated)
}
}
```
### Child snapshots
```swift
let childSnapshot = sectionSnapshot.snapshot(for: parent, includingParent: false)
```

### Expanding and collapsing items
* Expansion state is persisted. Expansion state is managed as part of a section snapshot's state.
* Call `apply(_:to)` to commit changes.
* Automatic animations.

```swift
struct NSDiffableDataSourceSectionSnapshot<Item: Hashable> {
func expand(_ items: [Item])
func collapse(_ items: [Item])
func isExpanded(_ item: Item) -> Bool
}
```

### [Section snapshot handlers](https://developer.apple.com/documentation/uikit/uicollectionviewdiffabledatasource/3600966-sectionsnapshothandlers)
To be notified about expansion state changes caused by these user interactions.

```swift
// Section Snapshot Handlers: handling user interactions for expand / collapse state changes

extension UICollectionViewDiffableDataSource {

struct SectionSnapshotHandlers<Item> {
var shouldExpandItem: ((Item) -> Bool)?
var willExpandItem: ((Item) -> Void)?

var shouldCollapseItem: ((Item) -> Bool)?
var willCollapseItem: ((Item) -> Void)?

var snapshotForExpandingParent: ((Item, NSDiffableDataSourceSectionSnapshot<Item>) -> NSDiffableDataSourceSectionSnapshot<Item>)?
}

var sectionSnapshotHandlers: SectionSnapshotHandlers<Item>

}
```
* SectionSnapshotHandlers type is a struct which is generic over item and contains five optional closures.
* If `shouldCollapseItem` return `false`, it will avoid particular parent collapsing the outline.
* `snapshotForExpandingParent` for lazy loading expensive content.

## Reordering Support
* Automatic snapshot updates.
* Transactions.

### [Reordering Handlers](https://developer.apple.com/documentation/uikit/uicollectionviewdiffabledatasource/reorderinghandlers)
To be notified that a user-initiated reordering interaction took place so that it can persist the new visual order to the application's backing store, which is its final source of truth.

```swift
// Diffable Data Source Reordering Handlers

extension UICollectionViewDiffableDataSource {

struct ReorderingHandlers {
var canReorderItem: ((Item) -> Bool)?
var willReorder: ((NSDiffableDataSourceTransaction<Section, Item>) -> Void)?
var didReorder: ((NSDiffableDataSourceTransaction<Section, Item>) -> Void)?
}

var reorderingHandlers: ReorderingHandlers
}
```

* Automatic reordering.
* A struct which contains three optional closures: `canReorderItem`, `willReorder`, and `didReorder`.
* First need to supply a `canReorderItem` closure.
* When the user is done with the reordering interaction, the `didReorder` closure is called.
* Must provide both the `canReorderItem` and `didReorder` closure to enable the reordering feature.

### [Reordering Transactions](https://developer.apple.com/documentation/uikit/nsdiffabledatasourcetransaction)
A transaction that describes the changes after reordering the items in the view.

```swift
struct NSDiffableDataSourceTransaction<Section, Item> {
var initialSnapshot: NSDiffableDataSourceSnapshot<Section, Item> { get }
var finalSnapshot: NSDiffableDataSourceSnapshot<Section, Item> { get }
var difference: CollectionDifference<Item> { get }
var sectionTransactions: [NSDiffableDataSourceSectionTransaction<Section, Item>] { get }
}
```
* `initialSnapshot` is the state of the Diffable Data Source before the update is applied.
* `finalSnapshot` is the state of the Diffable Data Source after the update is applied.
* Apply the data directly to `difference`, if use a data type such as `Array` for the source of truth.
* `sectionTransactions` provides per-section details about all the sections involved in this reordering update.

#### [Section Transactions](https://developer.apple.com/documentation/uikit/nsdiffabledatasourcesectiontransaction)
```swift
struct NSDiffableDataSourceSectionTransaction<Section, Item> {
var sectionIdentifier: Section { get }
var initialSnapshot: NSDiffableDataSourceSectionSnapshot<Item> { get }
var finalSnapshot: NSDiffableDataSourceSectionSnapshot<Item> { get }
var difference: CollectionDifference<Item> { get }
}
```
* `sectionIdentifier` for inspecting which section this sectionTransaction has been applied to.

#### Example
```swift
dataSource.reorderingHandlers.didReorder = { [weak self] transaction in
guard let self = self else { return }

if let updateBackingStore = self.backingStore.applying(transaction.difference) {
self.backingStore = updatedBackingStore
}
}
```

[section_snapshots]: ../../../images/notes/wwdc20/10045/section_snapshots.png
101 changes: 101 additions & 0 deletions content/notes/wwdc20/10097.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
---
contributors: dasauto
---
# Sample Code
Download the [sample code](https://developer.apple.com/documentation/uikit/views_and_controls/collection_views/implementing_modern_collection_views) to learn more about Modern Collection Views.

# Modern Collection View APIs Overview
![][modern_collection_view_apis]

# Diffable Data Source
## Recap

* Introduced in iOS 13.
* Simplifies UI State.
* Automatic animations.
* More to watch session [220](https://developer.apple.com/videos/play/wwdc2019/220) from WWDC 19: Advances in UI Data Sources.

## New to iOS 14
### [Section Snapshots](https://developer.apple.com/documentation/uikit/nsdiffabledatasourcesectionsnapshot)
* It encapsulates the data for a single section in a UICollectionView.
* Allow data sources to be more composable into section-sized chunks of data. (It's able to present same data use different layout in different sections.)
* Allow modeling of hierarchical data, which is needed to support rendering outline-style UIs.

#### Examples
![][section_snapshots]

* Top: Horizontally scrolling section.
* Middle: Outline style section.
* Bottom: List section.

More to watch session [10045](https://developer.apple.com/videos/play/wwdc2020/10045/): Advances in diffable data sources. → [Note](10045)

# Compositional Layout
## Recap
* Introduced in iOS 13.
* Allow us to build rich, complex layouts by composing smaller, easy-to-reason bits of layout together.
* Describe what you want the layout to look like instead of how the layout ought to work.
* Provide section-specific layouts.
* More to watch session [215](https://developer.apple.com/videos/play/wwdc2019/215) from WWDC 19: Advances in Collection View Layout.

## New to iOS 14
### [Lists](https://developer.apple.com/documentation/uikit/uicollectionviewcompositionallayout)
* UITableView like appearance.
* Lists are rich with features like swipe actions and many common cell layouts.
* List is built on top of Compositional Layout.
* New concrete UICollectionViewListCell.
* Header and footer support
* Sidebar appearance.

#### Examples
Creating a UICollectionViewLayout where every section in the collection view is a list with an inset grouped appearance.

```swift
let configuration = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
let layout = UICollectionViewCompositionalLayout.list(using: configuration)
```

More to watch session [10026](https://developer.apple.com/wwdc20/10026): Lists in UICollectionView.

# Modern Cells
## [Cell Registrations](https://developer.apple.com/documentation/uikit/uicollectionview/cellregistration)
* A brand new way to configure cells.
* A simple, re-usable way to set up a cell from a view model.
* Eliminate the extra step of registering a cell class or nib to associate it with a re-use identifier.
* Use a generic registration type which incorporates a configuration closure for setting up a new cell from a view model.

```swift
let reg = UICollectionView.CellRegistration<MyCell, ViewModel> { cell, indexPath, model in
// configure cell content
}

let dataSource = UICollectionViewDiffableDataSource<S,I>(collectionView: collectionView) {
collectionView, indexPath, item -> UICollectionViewCell in
return collectionView.dequeueConfiguredReusableCell(using: reg, for: indexPath, item: item)
}
```

## [Cell Content Configurations](https://developer.apple.com/documentation/uikit/uilistcontentconfiguration)
* Similar to UITableViewCell types.
* Use with any cell or even a generic UI view.
* Flexible.
* Lightweight.

```swift
var contentConfiguration = UIListContentConfiguration.cell()
contentConfiguration.image = UIImage(systemNamed:"hammer")
contentConfiguration.text = "Ready. Set. Code"
cell.contentConfiguration = contentConfiguration
```

## [Background Configurations](https://developer.apple.com/documentation/uikit/uibackgroundconfiguration)
* Similar to content configurations but applied to any cell's background with the ability to adjust properties such as color, border styles, and more.

```swift
cell.backgroundConfiguration = UIBackgroundConfiguration.clear()
```

More to watch session [10027](https://developer.apple.com/wwdc20/10027): Modern cell configuration.

[modern_collection_view_apis]: ../../../images/notes/wwdc20/10097/modern_collection_view_apis.png
[section_snapshots]: ../../../images/notes/wwdc20/10097/section_snapshots.png
Binary file added images/notes/wwdc20/10045/section_snapshots.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/notes/wwdc20/10097/section_snapshots.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.