Slather logo

Coverage for "ChatLayoutAttributes.swift" : 19.61%

(10 of 51 relevant lines covered)

ChatLayout/Classes/Core/ChatLayoutAttributes.swift

1
//
2
// ChatLayout
3
// ChatLayoutAttributes.swift
4
// https://github.com/ekazaev/ChatLayout
5
//
6
// Created by Eugene Kazaev in 2020-2022.
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
}