diff --git a/MagazineLayout/Public/MagazineLayout.swift b/MagazineLayout/Public/MagazineLayout.swift index 42d3f03..341977d 100755 --- a/MagazineLayout/Public/MagazineLayout.swift +++ b/MagazineLayout/Public/MagazineLayout.swift @@ -266,6 +266,8 @@ public final class MagazineLayout: UICollectionViewLayout { } stagedContentOffsetAdjustment = nil + targetContentOffsetCompensatingYOffsetForAppearingItem = nil + super.finalizeCollectionViewUpdates() } @@ -395,7 +397,8 @@ public final class MagazineLayout: UICollectionViewLayout { } let itemFrame = modelState.frameForItem(at: itemLocation, .afterUpdates) - return itemLayoutAttributes(for: itemLocation, frame: itemFrame) + let attributes = itemLayoutAttributes(for: itemLocation, frame: itemFrame) + return attributes } override public func layoutAttributesForSupplementaryView( @@ -449,6 +452,9 @@ public final class MagazineLayout: UICollectionViewLayout { initialLayoutAttributesForInsertedItemAt: itemIndexPath, byModifying: $0) } + + attributes?.frame.origin.y += targetContentOffsetCompensatingYOffsetForAppearingItem ?? 0 + itemLayoutAttributesForPendingAnimations[itemIndexPath] = attributes return attributes } else if @@ -459,7 +465,7 @@ public final class MagazineLayout: UICollectionViewLayout { { return previousLayoutAttributesForItem(at: initialIndexPath) } else { - return super.layoutAttributesForItem(at: itemIndexPath) + return super.initialLayoutAttributesForAppearingItem(at: itemIndexPath) } } @@ -490,7 +496,7 @@ public final class MagazineLayout: UICollectionViewLayout { itemLayoutAttributesForPendingAnimations[finalIndexPath] = attributes return attributes } else { - return super.layoutAttributesForItem(at: itemIndexPath) + return super.finalLayoutAttributesForDisappearingItem(at: itemIndexPath) } } @@ -691,10 +697,12 @@ public final class MagazineLayout: UICollectionViewLayout { contentOffsetAdjustment = nil } - let layoutAttributesForPendingAnimation = itemLayoutAttributesForPendingAnimations[preferredAttributes.indexPath] - layoutAttributesForPendingAnimation?.frame.size.height = modelState.frameForItem( - at: ElementLocation(indexPath: preferredAttributes.indexPath), - .afterUpdates).height + if let attributes = itemLayoutAttributesForPendingAnimations[preferredAttributes.indexPath] { + attributes.frame.size.height = modelState.frameForItem( + at: ElementLocation(indexPath: preferredAttributes.indexPath), + .afterUpdates).height + attributes.frame.origin.y -= (contentOffsetAdjustment?.y ?? 0) + } case .supplementaryView: contentOffsetAdjustment = nil @@ -755,6 +763,7 @@ public final class MagazineLayout: UICollectionViewLayout { override public func invalidateLayout(with context: UICollectionViewLayoutInvalidationContext) { guard let context = context as? MagazineLayoutInvalidationContext else { assertionFailure("`context` must be an instance of `MagazineLayoutInvalidationContext`") + super.invalidateLayout(with: context) return } @@ -797,6 +806,9 @@ public final class MagazineLayout: UICollectionViewLayout { } let yOffset = yOffset(for: targetContentOffsetAnchor) + + targetContentOffsetCompensatingYOffsetForAppearingItem = proposedContentOffset.y - yOffset + return CGPoint(x: proposedContentOffset.x, y: yOffset) } @@ -840,6 +852,7 @@ public final class MagazineLayout: UICollectionViewLayout { // animations will start from the estimated height. private var itemLayoutAttributesForPendingAnimations = [IndexPath: UICollectionViewLayoutAttributes]() private var supplementaryViewLayoutAttributesForPendingAnimations = [IndexPath: UICollectionViewLayoutAttributes]() + private var targetContentOffsetCompensatingYOffsetForAppearingItem: CGFloat? private struct PrepareActions: OptionSet { let rawValue: UInt @@ -862,13 +875,6 @@ public final class MagazineLayout: UICollectionViewLayout { // Used to provide the model state with the current visible bounds for the sole purpose of // supporting pinned headers and footers. private var currentVisibleBounds: CGRect { - let contentInset: UIEdgeInsets - if #available(iOS 11.0, tvOS 11.0, *) { - contentInset = currentCollectionView.adjustedContentInset - } else { - contentInset = currentCollectionView.contentInset - } - let refreshControlHeight: CGFloat #if os(iOS) if