Slather logo

Coverage for "ContainerCollectionViewCell.swift" : 0.00%

(0 of 20 relevant lines covered)

ChatLayout/Classes/Extras/ContainerCollectionViewCell.swift

1
//
2
// ChatLayout
3
// ContainerCollectionViewCell.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
/// A container `UICollectionViewCell` that constraints its contained view to its margins.
14
public final class ContainerCollectionViewCell<CustomView: UIView>: UICollectionViewCell {
15
16
    /// Default reuse identifier is set with the class name.
17
    public static var reuseIdentifier: String {
18
        return String(describing: self)
19
    }
20
21
    /// Contained view.
22
    public lazy var customView = CustomView(frame: bounds)
23
24
    /// An instance of `ContainerCollectionViewCellDelegate`
25
    public weak var delegate: ContainerCollectionViewCellDelegate?
26
27
    /// Initializes and returns a newly allocated view object with the specified frame rectangle.
28
    /// - Parameter frame: The frame rectangle for the view, measured in points. The origin of the frame is relative
29
    ///   to the superview in which you plan to add it.
30
    override init(frame: CGRect) {
31
        super.init(frame: frame)
32
        setupSubviews()
33
    }
34
35
    @available(*, unavailable, message: "Use init(reuseIdentifier:) instead")
36
    /// This constructor is unavailable.
37
    public required init?(coder aDecoder: NSCoder) {
38
        fatalError("init(coder:) has not been implemented")
39
    }
40
41
    /// Performs any clean up necessary to prepare the view for use again.
42
    public override func prepareForReuse() {
43
        super.prepareForReuse()
44
        delegate?.prepareForReuse()
45
    }
46
!
47
    /// Gives the cell a chance to modify the attributes provided by the layout object.
48
    /// - Parameter layoutAttributes: The attributes provided by the layout object. These attributes represent the values that the layout intends to apply to the cell.
!
49
    /// - Returns: Modified `UICollectionViewLayoutAttributes`
!
50
    public override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
!
51
        guard let chatLayoutAttributes = layoutAttributes as? ChatLayoutAttributes else {
52
            return super.preferredLayoutAttributesFitting(layoutAttributes)
!
53
        }
54
        delegate?.apply(chatLayoutAttributes)
!
55
        let resultingLayoutAttributes: ChatLayoutAttributes
56
        if let preferredLayoutAttributes = delegate?.preferredLayoutAttributesFitting(chatLayoutAttributes) {
57
            resultingLayoutAttributes = preferredLayoutAttributes
58
        } else if let chatLayoutAttributes = super.preferredLayoutAttributesFitting(chatLayoutAttributes) as? ChatLayoutAttributes {
59
            delegate?.modifyPreferredLayoutAttributesFitting(chatLayoutAttributes)
60
            resultingLayoutAttributes = chatLayoutAttributes
61
        } else {
62
            resultingLayoutAttributes = chatLayoutAttributes
!
63
        }
!
64
        return resultingLayoutAttributes
!
65
    }
66
67
    /// Applies the specified layout attributes to the view.
68
    /// - Parameter layoutAttributes: The layout attributes to apply.
69
    public override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) {
70
        guard let chatLayoutAttributes = layoutAttributes as? ChatLayoutAttributes else {
71
            return
72
        }
73
        super.apply(layoutAttributes)
74
        delegate?.apply(chatLayoutAttributes)
75
    }
!
76
!
77
    private func setupSubviews() {
!
78
        contentView.addSubview(customView)
!
79
        translatesAutoresizingMaskIntoConstraints = false
80
        insetsLayoutMarginsFromSafeArea = false
81
        layoutMargins = .zero
82
!
83
        contentView.insetsLayoutMarginsFromSafeArea = false
!
84
        contentView.layoutMargins = .zero
!
85
86
        customView.translatesAutoresizingMaskIntoConstraints = false
87
        customView.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor).isActive = true
!
88
        customView.trailingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.trailingAnchor).isActive = true
!
89
        customView.topAnchor.constraint(equalTo: contentView.layoutMarginsGuide.topAnchor).isActive = true
!
90
        customView.bottomAnchor.constraint(equalTo: contentView.layoutMarginsGuide.bottomAnchor).isActive = true
!
91
    }
92
93
}