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