| 1 |
//
|
|
| 2 |
// ChatLayout
|
|
| 3 |
// ChatLayoutDelegate.swift
|
|
| 4 |
// https://github.com/ekazaev/ChatLayout
|
|
| 5 |
//
|
|
| 6 |
// Created by Eugene Kazaev in 2020-2023.
|
|
| 7 |
// Distributed under the MIT license.
|
|
| 8 |
//
|
|
| 9 |
// Become a sponsor:
|
|
| 10 |
// https://github.com/sponsors/ekazaev
|
|
| 11 |
//
|
|
| 12 |
|
|
| 13 |
import Foundation
|
|
| 14 |
import UIKit
|
|
| 15 |
|
|
| 16 |
/// Represents the point in time when `CollectionViewChatLayout` asks about layout attributes modification.
|
|
| 17 |
public enum InitialAttributesRequestType: Hashable {
|
|
| 18 |
|
|
| 19 |
/// `UICollectionView` initially asks about the layout of an item.
|
|
| 20 |
case initial
|
|
| 21 |
|
|
| 22 |
/// An item is being invalidated.
|
|
| 23 |
case invalidation
|
|
| 24 |
|
|
| 25 |
}
|
|
| 26 |
|
|
| 27 |
/// `CollectionViewChatLayout` delegate
|
|
| 28 |
public protocol ChatLayoutDelegate: AnyObject {
|
|
| 29 |
|
|
| 30 |
/// `CollectionViewChatLayout` will call this method to ask if it should present the header in the current layout.
|
|
| 31 |
/// - Parameters:
|
|
| 32 |
/// - chatLayout: `CollectionViewChatLayout` reference.
|
|
| 33 |
/// - sectionIndex: Index of the section.
|
|
| 34 |
/// - Returns: `Bool`.
|
|
| 35 |
func shouldPresentHeader(_ chatLayout: CollectionViewChatLayout,
|
|
| 36 |
at sectionIndex: Int) -> Bool
|
|
| 37 |
|
|
| 38 |
/// `CollectionViewChatLayout` will call this method to ask if it should present the footer in the current layout.
|
|
| 39 |
/// - Parameters:
|
|
| 40 |
/// - chatLayout: `CollectionViewChatLayout` reference.
|
|
| 41 |
/// - sectionIndex: Index of the section.
|
|
| 42 |
/// - Returns: `Bool`.
|
|
| 43 |
func shouldPresentFooter(_ chatLayout: CollectionViewChatLayout,
|
|
| 44 |
at sectionIndex: Int) -> Bool
|
|
| 45 |
|
|
| 46 |
/// `CollectionViewChatLayout` will call this method to ask what size the item should have.
|
|
| 47 |
///
|
|
| 48 |
/// **NB:**
|
|
| 49 |
///
|
|
| 50 |
/// If you are trying to speed up the layout process by returning exact item sizes in this method -
|
|
| 51 |
/// do not forget to change `UICollectionReusableView.preferredLayoutAttributesFitting(...)` method and do not
|
|
| 52 |
/// call `super.preferredLayoutAttributesFitting(...)` there as it will measure the `UIView`
|
|
| 53 |
/// using Autolayout Engine anyway.
|
|
| 54 |
///
|
|
| 55 |
/// - Parameters:
|
|
| 56 |
/// - chatLayout: `CollectionViewChatLayout` reference.
|
|
| 57 |
/// - kind: Type of element represented by `ItemKind`.
|
|
| 58 |
/// - indexPath: Index path of the item.
|
|
| 59 |
/// - Returns: `ItemSize`.
|
|
| 60 |
func sizeForItem(_ chatLayout: CollectionViewChatLayout,
|
|
| 61 |
of kind: ItemKind,
|
|
| 62 |
at indexPath: IndexPath) -> ItemSize
|
|
| 63 |
|
|
| 64 |
/// `CollectionViewChatLayout` will call this method to ask what type of alignment the item should have.
|
|
| 65 |
/// - Parameters:
|
|
| 66 |
/// - chatLayout: `CollectionViewChatLayout` reference.
|
|
| 67 |
/// - kind: Type of element represented by `ItemKind`.
|
|
| 68 |
/// - indexPath: Index path of the item.
|
|
| 69 |
/// - Returns: `ChatItemAlignment`.
|
|
| 70 |
func alignmentForItem(_ chatLayout: CollectionViewChatLayout,
|
|
| 71 |
of kind: ItemKind,
|
|
| 72 |
at indexPath: IndexPath) -> ChatItemAlignment
|
|
| 73 |
|
|
| 74 |
/// Asks the delegate to modify a layout attributes instance so that it represents the initial visual state of an item
|
|
| 75 |
/// being inserted.
|
|
| 76 |
///
|
|
| 77 |
/// The `originalAttributes` instance is a reference type, and therefore can be modified directly.
|
|
| 78 |
///
|
|
| 79 |
/// - Parameters:
|
|
| 80 |
/// - chatLayout: `CollectionViewChatLayout` reference.
|
|
| 81 |
/// - kind: Type of element represented by `ItemKind`.
|
|
| 82 |
/// - indexPath: Index path of the item.
|
|
| 83 |
/// - originalAttributes: `ChatLayoutAttributes` that the `CollectionViewChatLayout` is going to use.
|
|
| 84 |
/// - state: `InitialAttributesRequestType` instance. Represents when is this method being called.
|
|
| 85 |
func initialLayoutAttributesForInsertedItem(_ chatLayout: CollectionViewChatLayout,
|
|
| 86 |
of kind: ItemKind,
|
|
| 87 |
at indexPath: IndexPath,
|
|
| 88 |
modifying originalAttributes: ChatLayoutAttributes,
|
|
| 89 |
on state: InitialAttributesRequestType)
|
|
| 90 |
|
|
| 91 |
/// Asks the delegate to modify a layout attributes instance so that it represents the final visual state of an item
|
|
| 92 |
/// being removed via `UICollectionView.deleteSections(_:)`.
|
|
| 93 |
///
|
|
| 94 |
/// The `originalAttributes` instance is a reference type, and therefore can be modified directly.
|
|
| 95 |
///
|
|
| 96 |
/// - Parameters:
|
|
| 97 |
/// - chatLayout: `CollectionViewChatLayout` reference.
|
|
| 98 |
/// - kind: Type of element represented by `ItemKind`.
|
|
| 99 |
/// - indexPath: Index path of the item.
|
|
| 100 |
/// - originalAttributes: `ChatLayoutAttributes` that the `CollectionViewChatLayout` is going to use.
|
|
| 101 |
func finalLayoutAttributesForDeletedItem(_ chatLayout: CollectionViewChatLayout,
|
|
| 102 |
of kind: ItemKind,
|
|
| 103 |
at indexPath: IndexPath,
|
|
| 104 |
modifying originalAttributes: ChatLayoutAttributes)
|
|
| 105 |
|
|
| 106 |
}
|
|
| 107 |
|
|
| 108 |
/// Default extension.
|
|
| 109 |
public extension ChatLayoutDelegate {
|
|
| 110 |
|
|
| 111 |
/// Default implementation returns: `false`.
|
|
| 112 |
func shouldPresentHeader(_ chatLayout: CollectionViewChatLayout,
|
|
| 113 |
at sectionIndex: Int) -> Bool {
|
! |
| 114 |
false
|
! |
| 115 |
}
|
! |
| 116 |
|
|
| 117 |
/// Default implementation returns: `false`.
|
|
| 118 |
func shouldPresentFooter(_ chatLayout: CollectionViewChatLayout,
|
|
| 119 |
at sectionIndex: Int) -> Bool {
|
! |
| 120 |
false
|
! |
| 121 |
}
|
! |
| 122 |
|
|
| 123 |
/// Default implementation returns: `ItemSize.auto`.
|
|
| 124 |
func sizeForItem(_ chatLayout: CollectionViewChatLayout,
|
|
| 125 |
of kind: ItemKind,
|
|
| 126 |
at indexPath: IndexPath) -> ItemSize {
|
! |
| 127 |
.auto
|
! |
| 128 |
}
|
! |
| 129 |
|
|
| 130 |
/// Default implementation returns: `ChatItemAlignment.fullWidth`.
|
|
| 131 |
func alignmentForItem(_ chatLayout: CollectionViewChatLayout,
|
|
| 132 |
of kind: ItemKind,
|
|
| 133 |
at indexPath: IndexPath) -> ChatItemAlignment {
|
! |
| 134 |
.fullWidth
|
! |
| 135 |
}
|
! |
| 136 |
|
|
| 137 |
/// Default implementation sets a `ChatLayoutAttributes.alpha` to zero.
|
|
| 138 |
func initialLayoutAttributesForInsertedItem(_ chatLayout: CollectionViewChatLayout,
|
|
| 139 |
of kind: ItemKind,
|
|
| 140 |
at indexPath: IndexPath,
|
|
| 141 |
modifying originalAttributes: ChatLayoutAttributes,
|
|
| 142 |
on state: InitialAttributesRequestType) {
|
! |
| 143 |
originalAttributes.alpha = 0
|
! |
| 144 |
}
|
! |
| 145 |
|
|
| 146 |
/// Default implementation sets a `ChatLayoutAttributes.alpha` to zero.
|
|
| 147 |
func finalLayoutAttributesForDeletedItem(_ chatLayout: CollectionViewChatLayout,
|
|
| 148 |
of kind: ItemKind,
|
|
| 149 |
at indexPath: IndexPath,
|
|
| 150 |
modifying originalAttributes: ChatLayoutAttributes) {
|
! |
| 151 |
originalAttributes.alpha = 0
|
! |
| 152 |
}
|
! |
| 153 |
|
|
| 154 |
}
|
|