This repository has been archived on 2026-05-26. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
avh-plan-ios/Pods/MagazineLayout/MagazineLayout/Public/Views/MagazineLayoutCollectionViewCell.swift
T

89 lines
4.0 KiB
Swift

// Created by bryankeller on 11/29/18.
// Copyright © 2018 Airbnb, Inc.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import UIKit
/// A cell that coordinates with `MagazineLayoutCollectionViewLayoutAttributes` to determine how to
/// size itself: with self-sizing, or without self-sizing. Use this class (or subclasses) for
/// displaying cells with `MagazineLayout`.
///
/// Note that this class is very similar to `MagazineLayoutCollectionReusableView`.
///
/// `UIKit` invokes `preferredLayoutAttributesFitting(_:)` with an initial set of layout attributes,
/// giving this cell subclass a chance to modify the `size` property of the attributes based on
/// whether or not we want to self-size.
///
/// Subclassing and/or adding additional protocol conformances is encouraged, although modifying
/// the behavior of `preferredLayoutAttributesFitting(_:)` is not recommended.
///
/// This class exists because `MagazineLayout` supports self-sizing in just the vertical dimension -
/// a use case that `UICollectionViewCell` does not support out-of-the-box.
///
/// As of iOS 12, `UICollectionReusableView` is tightly coupled with `UICollectionViewFlowLayout`'s
/// private `_estimatesSizes` property, which is used to determine how to size cells displayed in a
/// `UICollectionViewFlowLayout`. If `_estimatesSizes` is `true`, then `UICollectionReusableView`
/// will self-size in both the horizontal and vertical dimensions. If it is `false`, no self-sizing
/// will occur. In short, `UICollectionReusableView` is only optimized to work correctly with
/// Apple's own layout.
open class MagazineLayoutCollectionViewCell: UICollectionViewCell {
override open func preferredLayoutAttributesFitting(
_ layoutAttributes: UICollectionViewLayoutAttributes)
-> UICollectionViewLayoutAttributes
{
guard let attributes = layoutAttributes as? MagazineLayoutCollectionViewLayoutAttributes else {
assertionFailure("`layoutAttributes` must be an instance of `MagazineLayoutCollectionViewLayoutAttributes`")
return super.preferredLayoutAttributesFitting(layoutAttributes)
}
// In some cases, `contentView`'s required width and height constraints
// (created from its auto-resizing mask) will not have the correct constants before invoking
// `systemLayoutSizeFitting(...)`, causing the cell to size incorrectly. This seems to be a
// UIKit bug.
// https://openradar.appspot.com/radar?id=5025850143539200
// The issue seems most common when the collection view's bounds change (on rotation).
// We correct for this by updating `contentView.bounds`, which updates the constants used by the
// width and height constraints created by the `contentView`'s auto-resizing mask.
if contentView.bounds.width != layoutAttributes.size.width {
contentView.bounds.size.width = layoutAttributes.size.width
}
if
!attributes.shouldVerticallySelfSize &&
contentView.bounds.height != layoutAttributes.size.height
{
contentView.bounds.size.height = layoutAttributes.size.height
}
let size: CGSize
if attributes.shouldVerticallySelfSize {
// Self-sizing is required in the vertical dimension.
size = super.systemLayoutSizeFitting(
layoutAttributes.size,
withHorizontalFittingPriority: .required,
verticalFittingPriority: .fittingSizeLevel)
} else {
// No self-sizing is required; respect whatever size the layout determined.
size = layoutAttributes.size
}
layoutAttributes.size = size
return layoutAttributes
}
}