| 1 |
//
|
|
| 2 |
// ChatLayout
|
|
| 3 |
// ChatLayoutAttributes.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 |
/// Custom implementation of `UICollectionViewLayoutAttributes`
|
|
| 17 |
public final class ChatLayoutAttributes: UICollectionViewLayoutAttributes {
|
|
| 18 |
|
|
| 19 |
/// Alignment of the current item. Can be changed within `UICollectionViewCell.preferredLayoutAttributesFitting(...)`
|
|
| 20 |
public var alignment: ChatItemAlignment = .fullWidth
|
354x |
| 21 |
|
|
| 22 |
/// `CollectionViewChatLayout`s additional insets setup using `ChatLayoutSettings`. Added for convenience.
|
|
| 23 |
public internal(set) var additionalInsets: UIEdgeInsets = .zero
|
354x |
| 24 |
|
|
| 25 |
/// `UICollectionView`s frame size. Added for convenience.
|
|
| 26 |
public internal(set) var viewSize: CGSize = .zero
|
354x |
| 27 |
|
|
| 28 |
/// `UICollectionView`s adjusted content insets. Added for convenience.
|
|
| 29 |
public internal(set) var adjustedContentInsets: UIEdgeInsets = .zero
|
354x |
| 30 |
|
|
| 31 |
/// `CollectionViewChatLayout`s visible bounds size excluding `adjustedContentInsets`. Added for convenience.
|
|
| 32 |
public internal(set) var visibleBoundsSize: CGSize = .zero
|
354x |
| 33 |
|
|
| 34 |
/// `CollectionViewChatLayout`s visible bounds size excluding `adjustedContentInsets` and `additionalInsets`. Added for convenience.
|
|
| 35 |
public internal(set) var layoutFrame: CGRect = .zero
|
354x |
| 36 |
|
|
| 37 |
#if DEBUG
|
|
| 38 |
var id: UUID?
|
|
| 39 |
#endif
|
|
| 40 |
|
|
| 41 |
convenience init(kind: ItemKind, indexPath: IndexPath = IndexPath(item: 0, section: 0)) {
|
! |
| 42 |
switch kind {
|
! |
| 43 |
case .cell:
|
! |
| 44 |
self.init(forCellWith: indexPath)
|
! |
| 45 |
case .header:
|
! |
| 46 |
self.init(forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, with: indexPath)
|
! |
| 47 |
case .footer:
|
! |
| 48 |
self.init(forSupplementaryViewOfKind: UICollectionView.elementKindSectionFooter, with: indexPath)
|
! |
| 49 |
}
|
! |
| 50 |
}
|
! |
| 51 |
|
|
| 52 |
/// Returns an exact copy of `ChatLayoutAttributes`.
|
|
| 53 |
public override func copy(with zone: NSZone? = nil) -> Any {
|
! |
| 54 |
let copy = super.copy(with: zone) as! ChatLayoutAttributes
|
! |
| 55 |
copy.viewSize = viewSize
|
! |
| 56 |
copy.alignment = alignment
|
! |
| 57 |
copy.layoutFrame = layoutFrame
|
! |
| 58 |
copy.additionalInsets = additionalInsets
|
! |
| 59 |
copy.visibleBoundsSize = visibleBoundsSize
|
! |
| 60 |
copy.adjustedContentInsets = adjustedContentInsets
|
! |
| 61 |
#if DEBUG
|
! |
| 62 |
copy.id = id
|
! |
| 63 |
#endif
|
! |
| 64 |
return copy
|
! |
| 65 |
}
|
! |
| 66 |
|
|
| 67 |
/// Returns a Boolean value indicating whether two `ChatLayoutAttributes` are considered equal.
|
|
| 68 |
public override func isEqual(_ object: Any?) -> Bool {
|
18x |
| 69 |
super.isEqual(object)
|
18x |
| 70 |
&& alignment == (object as? ChatLayoutAttributes)?.alignment
|
18x |
| 71 |
}
|
18x |
| 72 |
|
|
| 73 |
/// `ItemKind` represented by this attributes object.
|
|
| 74 |
public var kind: ItemKind {
|
! |
| 75 |
switch (representedElementCategory, representedElementKind) {
|
! |
| 76 |
case (.cell, nil):
|
! |
| 77 |
return .cell
|
! |
| 78 |
case (.supplementaryView, .some(UICollectionView.elementKindSectionHeader)):
|
! |
| 79 |
return .header
|
! |
| 80 |
case (.supplementaryView, .some(UICollectionView.elementKindSectionFooter)):
|
! |
| 81 |
return .footer
|
! |
| 82 |
default:
|
! |
| 83 |
preconditionFailure("Unsupported element kind.")
|
! |
| 84 |
}
|
! |
| 85 |
}
|
! |
| 86 |
|
|
| 87 |
func typedCopy() -> ChatLayoutAttributes {
|
! |
| 88 |
guard let typedCopy = copy() as? ChatLayoutAttributes else {
|
! |
| 89 |
fatalError("Internal inconsistency.")
|
! |
| 90 |
}
|
! |
| 91 |
return typedCopy
|
! |
| 92 |
}
|
! |
| 93 |
|
|
| 94 |
}
|
|