Skip to content

Commit

Permalink
Fix initial layout attributes when applying target content offset
Browse files Browse the repository at this point in the history
  • Loading branch information
bryankeller committed Mar 6, 2024
1 parent bfc6077 commit ea4253b
Showing 1 changed file with 20 additions and 14 deletions.
34 changes: 20 additions & 14 deletions MagazineLayout/Public/MagazineLayout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,8 @@ public final class MagazineLayout: UICollectionViewLayout {
}
stagedContentOffsetAdjustment = nil

targetContentOffsetCompensatingYOffsetForAppearingItem = nil

super.finalizeCollectionViewUpdates()
}

Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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
Expand All @@ -459,7 +465,7 @@ public final class MagazineLayout: UICollectionViewLayout {
{
return previousLayoutAttributesForItem(at: initialIndexPath)
} else {
return super.layoutAttributesForItem(at: itemIndexPath)
return super.initialLayoutAttributesForAppearingItem(at: itemIndexPath)
}
}

Expand Down Expand Up @@ -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)
}
}

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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)
}

Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down

0 comments on commit ea4253b

Please sign in to comment.