Skip to content

Commit

Permalink
Merge pull request rechsteiner#496 from rechsteiner/paging-collection…
Browse files Browse the repository at this point in the history
…-view-layout-tests

Add unit tests for PagingCollectionViewLayout
  • Loading branch information
rechsteiner authored Jun 6, 2020
2 parents cfc0908 + e05a661 commit d74a9bf
Show file tree
Hide file tree
Showing 9 changed files with 430 additions and 62 deletions.
4 changes: 4 additions & 0 deletions Parchment.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
95591F21222C3A0400677B4B /* PagingControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95591F20222C3A0400677B4B /* PagingControllerTests.swift */; };
95591F23222C522800677B4B /* PagingController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95591F22222C522800677B4B /* PagingController.swift */; };
9568922B222C525C00AFF250 /* CollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9568922A222C525C00AFF250 /* CollectionView.swift */; };
956EBE5E248BC426003ED4BA /* PagingCollectionViewLayoutTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 956EBE5D248BC426003ED4BA /* PagingCollectionViewLayoutTests.swift */; };
9575BEB32461FEF9002403F6 /* CreateDistance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9575BEB22461FEF9002403F6 /* CreateDistance.swift */; };
9575BEB52462034B002403F6 /* PagingDistanceRightTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9575BEB42462034B002403F6 /* PagingDistanceRightTests.swift */; };
9575BEB72463490B002403F6 /* PagingDistanceCenteredTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9575BEB62463490B002403F6 /* PagingDistanceCenteredTests.swift */; };
Expand Down Expand Up @@ -270,6 +271,7 @@
95591F20222C3A0400677B4B /* PagingControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PagingControllerTests.swift; sourceTree = "<group>"; };
95591F22222C522800677B4B /* PagingController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PagingController.swift; sourceTree = "<group>"; };
9568922A222C525C00AFF250 /* CollectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionView.swift; sourceTree = "<group>"; };
956EBE5D248BC426003ED4BA /* PagingCollectionViewLayoutTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PagingCollectionViewLayoutTests.swift; sourceTree = "<group>"; };
9575BEB22461FEF9002403F6 /* CreateDistance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateDistance.swift; sourceTree = "<group>"; };
9575BEB42462034B002403F6 /* PagingDistanceRightTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PagingDistanceRightTests.swift; sourceTree = "<group>"; };
9575BEB62463490B002403F6 /* PagingDistanceCenteredTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PagingDistanceCenteredTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -439,6 +441,7 @@
3E504EC81C7465B000AE1CE3 /* Info.plist */,
954E7DEB1F48AE1300342ECF /* Item.swift */,
95FEEA4424215FCA009B5B64 /* PageViewManagerTests.swift */,
956EBE5D248BC426003ED4BA /* PagingCollectionViewLayoutTests.swift */,
95591F20222C3A0400677B4B /* PagingControllerTests.swift */,
3E5E93E81CE7E093000762A1 /* PagingDataStructureTests.swift */,
954842621F4252070072038C /* PagingDiffTests.swift */,
Expand Down Expand Up @@ -958,6 +961,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
956EBE5E248BC426003ED4BA /* PagingCollectionViewLayoutTests.swift in Sources */,
9575BEB52462034B002403F6 /* PagingDistanceRightTests.swift in Sources */,
95FEEA512423F752009B5B64 /* MockPageViewManagerDataSource.swift in Sources */,
95D78FE1228715E100E6EE7C /* MockPagingControllerDataSource.swift in Sources */,
Expand Down
20 changes: 10 additions & 10 deletions Parchment/Classes/PagingCollectionViewLayout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,9 @@ open class PagingCollectionViewLayout: UICollectionViewLayout, PagingLayout {
}
}

/// Cache used to store the preferred item width for each
/// self-sizing cell. PagingItem identifier is used as the key.
private var widthCache: [Int: CGFloat] = [:]
/// Cache used to store the preferred item size for each self-sizing
/// cell. PagingItem identifier is used as the key.
private var preferredSizeCache: [Int: CGFloat] = [:]

private(set) var contentInsets: UIEdgeInsets = .zero
private var contentSize: CGSize = .zero
Expand Down Expand Up @@ -161,12 +161,12 @@ open class PagingCollectionViewLayout: UICollectionViewLayout, PagingLayout {
override open func shouldInvalidateLayout(forPreferredLayoutAttributes preferredAttributes: UICollectionViewLayoutAttributes, withOriginalAttributes originalAttributes: UICollectionViewLayoutAttributes) -> Bool {
switch options.menuItemSize {
// Invalidate the layout and update the layout attributes with the
// preferred width for each cell. The preferred width is based on
// preferred width for each cell. The preferred size is based on
// the layout constraints in each cell.
case .selfSizing where originalAttributes is PagingCellLayoutAttributes:
if preferredAttributes.frame.width != originalAttributes.frame.width {
let pagingItem = visibleItems.pagingItem(for: originalAttributes.indexPath)
widthCache[pagingItem.identifier] = preferredAttributes.frame.width
preferredSizeCache[pagingItem.identifier] = preferredAttributes.frame.width
return true
}
return false
Expand Down Expand Up @@ -276,8 +276,8 @@ open class PagingCollectionViewLayout: UICollectionViewLayout, PagingLayout {
let y = adjustedMenuInsets.top
let pagingItem = visibleItems.pagingItem(for: indexPath)

if sizeCache.implementsWidthDelegate {
var width = sizeCache.itemWidth(for: pagingItem)
if sizeCache.implementsSizeDelegate {
var width = sizeCache.itemSize(for: pagingItem)
let selectedWidth = sizeCache.itemWidthSelected(for: pagingItem)

if let currentPagingItem = state.currentPagingItem, currentPagingItem.isEqual(to: pagingItem) {
Expand All @@ -294,7 +294,7 @@ open class PagingCollectionViewLayout: UICollectionViewLayout, PagingLayout {
case let .sizeToFit(minWidth, height):
attributes.frame = CGRect(x: x, y: y, width: minWidth, height: height)
case let .selfSizing(estimatedWidth, height):
if let actualWidth = widthCache[pagingItem.identifier] {
if let actualWidth = preferredSizeCache[pagingItem.identifier] {
attributes.frame = CGRect(x: x, y: y, width: actualWidth, height: height)
} else {
attributes.frame = CGRect(x: x, y: y, width: estimatedWidth, height: height)
Expand All @@ -311,7 +311,7 @@ open class PagingCollectionViewLayout: UICollectionViewLayout, PagingLayout {
if previousFrame.maxX - adjustedMenuInsets.left < view.bounds.width {

switch (options.menuItemSize) {
case let .sizeToFit(_, height) where sizeCache.implementsWidthDelegate == false:
case let .sizeToFit(_, height) where sizeCache.implementsSizeDelegate == false:
let insets = adjustedMenuInsets.left + adjustedMenuInsets.right
let spacing = (options.menuItemSpacing * CGFloat(range.upperBound - 1))
let width = (view.bounds.width - insets - spacing) / CGFloat(range.upperBound)
Expand Down Expand Up @@ -531,7 +531,7 @@ open class PagingCollectionViewLayout: UICollectionViewLayout, PagingLayout {
y: attributes.center.y - attributes.bounds.midY,
width: attributes.bounds.width,
height: attributes.bounds.height)
if sizeCache.implementsWidthDelegate {
if sizeCache.implementsSizeDelegate {
let indexPath = IndexPath(item: index, section: 0)
let pagingItem = visibleItems.pagingItem(for: indexPath)

Expand Down
8 changes: 4 additions & 4 deletions Parchment/Classes/PagingController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ final class PagingController: NSObject {
collectionView.setContentOffset(contentOffset, animated: false)
}

if sizeCache.implementsWidthDelegate {
if sizeCache.implementsSizeDelegate {
invalidationContext.invalidateSizes = true
}
}
Expand Down Expand Up @@ -629,14 +629,14 @@ final class PagingController: NSObject {
if currentPagingItem.isEqual(to: pagingItem) {
return sizeCache.itemWidthSelected(for: pagingItem)
} else {
return sizeCache.itemWidth(for: pagingItem)
return sizeCache.itemSize(for: pagingItem)
}
}

private func configureSizeCache(for pagingItem: PagingItem) {
if sizeDelegate != nil {
sizeCache.implementsWidthDelegate = true
sizeCache.widthForPagingItem = { [weak self] item, selected in
sizeCache.implementsSizeDelegate = true
sizeCache.sizeForPagingItem = { [weak self] item, selected in
return self?.sizeDelegate?.width(for: item, isSelected: selected)
}
}
Expand Down
34 changes: 17 additions & 17 deletions Parchment/Classes/PagingSizeCache.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import UIKit
class PagingSizeCache {

var options: PagingOptions
var implementsWidthDelegate: Bool = false
var widthForPagingItem: ((PagingItem, Bool) -> CGFloat?)?
var implementsSizeDelegate: Bool = false
var sizeForPagingItem: ((PagingItem, Bool) -> CGFloat?)?

private var widthCache: [Int: CGFloat] = [:]
private var selectedWidthCache: [Int: CGFloat] = [:]
private var sizeCache: [Int: CGFloat] = [:]
private var selectedSizeCache: [Int: CGFloat] = [:]

init(options: PagingOptions) {
self.options = options
Expand Down Expand Up @@ -37,27 +37,27 @@ class PagingSizeCache {
}

func clear() {
self.widthCache = [:]
self.selectedWidthCache = [:]
self.sizeCache = [:]
self.selectedSizeCache = [:]
}

func itemWidth(for pagingItem: PagingItem) -> CGFloat {
if let width = widthCache[pagingItem.identifier] {
return width
func itemSize(for pagingItem: PagingItem) -> CGFloat {
if let size = sizeCache[pagingItem.identifier] {
return size
} else {
let width = widthForPagingItem?(pagingItem, false)
widthCache[pagingItem.identifier] = width
return width ?? options.estimatedItemWidth
let size = sizeForPagingItem?(pagingItem, false)
sizeCache[pagingItem.identifier] = size
return size ?? options.estimatedItemWidth
}
}

func itemWidthSelected(for pagingItem: PagingItem) -> CGFloat {
if let width = selectedWidthCache[pagingItem.identifier] {
return width
if let size = selectedSizeCache[pagingItem.identifier] {
return size
} else {
let width = widthForPagingItem?(pagingItem, true)
selectedWidthCache[pagingItem.identifier] = width
return width ?? options.estimatedItemWidth
let size = sizeForPagingItem?(pagingItem, true)
selectedSizeCache[pagingItem.identifier] = size
return size ?? options.estimatedItemWidth
}
}

Expand Down
18 changes: 9 additions & 9 deletions Parchment/Structs/PagingDistance.swift
Original file line number Diff line number Diff line change
Expand Up @@ -147,12 +147,12 @@ struct PagingDistance {
let originalDistance = distance
distance = contentSize - (contentOffset + viewSize)

if sizeCache.implementsWidthDelegate {
if sizeCache.implementsSizeDelegate {
let toWidth = sizeCache.itemWidthSelected(for: toItem)
distance += toWidth - toSize

if let _ = fromAttributes {
let fromWidth = sizeCache.itemWidth(for: fromItem)
let fromWidth = sizeCache.itemSize(for: fromItem)
distance -= fromSize - fromWidth
}

Expand Down Expand Up @@ -183,10 +183,10 @@ struct PagingDistance {
// backwards or the current item is scrolled out of view the
// difference doesn't matter as the change in frame of the current
// item won't have any affect on the position of the upcoming item.
if sizeCache.implementsWidthDelegate {
if sizeCache.implementsSizeDelegate {
if let _ = fromAttributes {
if fromItem.isBefore(item: toItem) {
let fromWidth = sizeCache.itemWidth(for: fromItem)
let fromWidth = sizeCache.itemSize(for: fromItem)
let fromDiff = fromSize - fromWidth
distance -= fromDiff
}
Expand All @@ -202,7 +202,7 @@ struct PagingDistance {
let width = contentOffset + viewSize
var distance = currentPosition - width

if sizeCache.implementsWidthDelegate {
if sizeCache.implementsSizeDelegate {
let toWidth = sizeCache.itemWidthSelected(for: toItem)

// If we have layout attributes for the current item it means
Expand All @@ -214,7 +214,7 @@ struct PagingDistance {
let toDiff = toWidth - toSize
distance += toDiff
} else {
let fromWidth = sizeCache.itemWidth(for: fromItem)
let fromWidth = sizeCache.itemSize(for: fromItem)
let fromDiff = fromSize - fromWidth
let toDiff = toWidth - toSize
distance -= fromDiff
Expand All @@ -240,9 +240,9 @@ struct PagingDistance {
let distanceBetweenCells = toCenter - fromCenter
distance = distanceBetweenCells - distanceToCenter

if sizeCache.implementsWidthDelegate {
if sizeCache.implementsSizeDelegate {
let toWidth = sizeCache.itemWidthSelected(for: toItem)
let fromWidth = sizeCache.itemWidth(for: fromItem)
let fromWidth = sizeCache.itemSize(for: fromItem)

if toItem.isBefore(item: fromItem) {
distance = -(toSize + (fromCenter - (toCenter + (toSize / 2))) - (toWidth / 2)) - distanceToCenter
Expand All @@ -251,7 +251,7 @@ struct PagingDistance {
distance = fromWidth + (toCenter - (fromCenter + (fromSize / 2))) + toDiff - (fromSize / 2) - distanceToCenter
}
}
} else if sizeCache.implementsWidthDelegate {
} else if sizeCache.implementsSizeDelegate {
let toWidth = sizeCache.itemWidthSelected(for: toItem)
let toDiff = toWidth - toSize
distance += toDiff / 2
Expand Down
Loading

0 comments on commit d74a9bf

Please sign in to comment.