refactored to not use KVO, but a publisher KVO

Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
Matt Bruce 2024-03-11 12:47:38 -05:00
parent 466dbb7c6a
commit 4733a3a00c

View File

@ -34,7 +34,6 @@ public final class SelfSizingCollectionView: UICollectionView {
//--------------------------------------------------
// MARK: - Private Properties
//--------------------------------------------------
private var contentSizeObservation: NSKeyValueObservation?
private var collectionViewHeight: NSLayoutConstraint?
private var anyCancellable: AnyCancellable?
@ -45,7 +44,6 @@ public final class SelfSizingCollectionView: UICollectionView {
/// The natural size for the receiving view, considering only properties of the view itself.
public override var intrinsicContentSize: CGSize {
let contentSize = self.contentSize
//print(#function, contentSize)
return CGSize(width: UIView.noIntrinsicMetric, height: contentSize.height)
}
@ -68,17 +66,21 @@ public final class SelfSizingCollectionView: UICollectionView {
setContentHuggingPriority(.required, for: .vertical)
setContentCompressionResistancePriority(.required, for: .vertical)
collectionViewHeight = heightAnchor.constraint(equalToConstant: 0).activate()
// Observing the value of contentSize seems to be the only reliable way to get the contentSize after the collection view lays out its subviews.
self.contentSizeObservation = self.observe(\.contentSize, options: [.old, .new]) { [weak self] _, change in
// If we don't specify `options: [.old, .new]`, the change.oldValue and .newValue will always be `nil`.
if change.newValue != change.oldValue {
self?.invalidateIntrinsicContentSize()
if let height = change.newValue?.height {
self?.collectionViewHeight?.constant = height
anyCancellable = self.publisher(for: \.contentSize, options: [.old, .new])
.scan((old: CGSize.zero, new: CGSize.zero)) { accumulator, newValue in
// accumulator.old contains the old contentSize value
// accumulator.new contains the new contentSize value before the current update
// newValue is the current update to contentSize
return (old: accumulator.new, new: newValue)
}
.sink { [weak self] compare in
if compare.old != compare.new {
print("Old contentSize: \(compare.old), New contentSize: \(compare.new)")
self?.invalidateIntrinsicContentSize()
self?.collectionViewHeight?.constant = compare.new.height
}
}
}
}
}