Skip to content

Commit

Permalink
Fix Invalid frame dimension
Browse files Browse the repository at this point in the history
  • Loading branch information
paololeonardi committed Feb 13, 2021
1 parent f425417 commit 22b9078
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 43 deletions.
15 changes: 8 additions & 7 deletions Sources/WaterfallGrid/WaterfallGrid.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,13 @@ public struct WaterfallGrid<Data, ID, Content>: View where Data : RandomAccessCo
self.grid(in: geometry)
.onPreferenceChange(ElementPreferenceKey.self, perform: { preferences in
DispatchQueue.global(qos: .userInteractive).async {
let alignmentGuides = self.calculateAlignmentGuides(columns: self.style.columns,
spacing: self.style.spacing,
scrollDirection: self.scrollOptions.direction,
preferences: preferences)
let (alignmentGuides, gridHeight) = self.alignmentsAndGridHeight(columns: self.style.columns,
spacing: self.style.spacing,
scrollDirection: self.scrollOptions.direction,
preferences: preferences)
DispatchQueue.main.async {
self.alignmentGuides = alignmentGuides
self.gridHeight = gridHeight
}
}
})
Expand Down Expand Up @@ -65,7 +66,7 @@ public struct WaterfallGrid<Data, ID, Content>: View where Data : RandomAccessCo

// MARK: - Helpers

func calculateAlignmentGuides(columns: Int, spacing: CGFloat, scrollDirection: Axis.Set, preferences: [ElementPreferenceData]) -> [AnyHashable: CGPoint] {
func alignmentsAndGridHeight(columns: Int, spacing: CGFloat, scrollDirection: Axis.Set, preferences: [ElementPreferenceData]) -> ([AnyHashable: CGPoint], CGFloat) {
var heights = Array(repeating: CGFloat(0), count: columns)
var alignmentGuides = [AnyHashable: CGPoint]()

Expand All @@ -82,9 +83,9 @@ public struct WaterfallGrid<Data, ID, Content>: View where Data : RandomAccessCo
}
}

gridHeight = (heights.max() ?? spacing) - spacing
let gridHeight = max(0, (heights.max() ?? spacing) - spacing)

return alignmentGuides
return (alignmentGuides, gridHeight)
}

func columnWidth(columns: Int, spacing: CGFloat, scrollDirection: Axis.Set, geometrySize: CGSize) -> CGFloat {
Expand Down
120 changes: 84 additions & 36 deletions Tests/WaterfallGridTests/WaterfallGridTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class WaterfallGridTests: XCTestCase {
super.tearDown()
}

func test_calculateAlignmentGuides_withSpacingAndVerticalScroll() {
func test_alignmentsAndGridHeight_withSpacingAndVerticalScroll() {
// Given
let width = 40
let spacing: CGFloat = 8
Expand Down Expand Up @@ -59,22 +59,23 @@ class WaterfallGridTests: XCTestCase {
4: CGPoint(x: -48, y: -88)
]

let testCases: [ ([AnyHashable : CGPoint], Int, UInt) ] = [
// expected | columns | line
(alignmentsOneColumn, 1, #line),
(alignmentsTwoColumns, 2, #line),
(alignmentsThreeColumns, 3, #line)
let testCases: [ ([AnyHashable : CGPoint], CGFloat, Int, UInt) ] = [
// expectedAlignments | expectedGridHeight | columns | line
(alignmentsOneColumn, 422.0, 1, #line),
(alignmentsTwoColumns, 228.0, 2, #line),
(alignmentsThreeColumns, 188.0, 3, #line)
]

for (expected, columns, line) in testCases {
for (expectedAlignments, expectedGridHeight, columns, line) in testCases {
// When
let result = sut.calculateAlignmentGuides(columns: columns, spacing: spacing, scrollDirection: scrollDirection, preferences: preferences)
let (alignments, gridHeight) = sut.alignmentsAndGridHeight(columns: columns, spacing: spacing, scrollDirection: scrollDirection, preferences: preferences)
// Then
XCTAssertEqual(expected, result, line: line)
XCTAssertEqual(expectedAlignments, alignments, line: line)
XCTAssertEqual(expectedGridHeight, gridHeight, line: line)
}
}

func test_calculateAlignmentGuides_withSpacingAndHorizontalScroll() {
func test_alignmentsAndGridHeight_withSpacingAndHorizontalScroll() {
// Given
let height = 40
let spacing: CGFloat = 8
Expand Down Expand Up @@ -111,22 +112,23 @@ class WaterfallGridTests: XCTestCase {
4: CGPoint(x: -88, y: -48)
]

let testCases: [ ([AnyHashable : CGPoint], Int, UInt) ] = [
// expected | columns | line
(alignmentsOneColumn, 1, #line),
(alignmentsTwoColumns, 2, #line),
(alignmentsThreeColumns, 3, #line)
let testCases: [ ([AnyHashable : CGPoint], CGFloat, Int, UInt) ] = [
// expectedAlignments | expectedGridHeight | columns | line
(alignmentsOneColumn, 422.0, 1, #line),
(alignmentsTwoColumns, 228.0, 2, #line),
(alignmentsThreeColumns, 188.0, 3, #line)
]

for (expected, columns, line) in testCases {
for (expectedAlignments, expectedGridHeight, columns, line) in testCases {
// When
let result = sut.calculateAlignmentGuides(columns: columns, spacing: spacing, scrollDirection: scrollDirection, preferences: preferences)
let (alignments, gridHeight) = sut.alignmentsAndGridHeight(columns: columns, spacing: spacing, scrollDirection: scrollDirection, preferences: preferences)
// Then
XCTAssertEqual(expected, result, line: line)
XCTAssertEqual(expectedAlignments, alignments, line: line)
XCTAssertEqual(expectedGridHeight, gridHeight, line: line)
}
}

func test_calculateAlignmentGuides_withoutSpacingAndVerticalScroll() {
func test_alignmentsAndGridHeight_withoutSpacingAndVerticalScroll() {
// Given
let width = 40
let spacing: CGFloat = 0
Expand Down Expand Up @@ -163,22 +165,23 @@ class WaterfallGridTests: XCTestCase {
4: CGPoint(x: -40, y: -80)
]

let testCases: [ ([AnyHashable : CGPoint], Int, UInt) ] = [
// expected | columns | line
(alignmentsOneColumn, 1, #line),
(alignmentsTwoColumns, 2, #line),
(alignmentsThreeColumns, 3, #line)
let testCases: [ ([AnyHashable : CGPoint], CGFloat, Int, UInt) ] = [
// expectedAlignments | expectedGridHeight | columns | line
(alignmentsOneColumn, 390.0, 1, #line),
(alignmentsTwoColumns, 220.0, 2, #line),
(alignmentsThreeColumns, 180.0, 3, #line)
]

for (expected, columns, line) in testCases {
for (expectedAlignments, expectedGridHeight, columns, line) in testCases {
// When
let result = sut.calculateAlignmentGuides(columns: columns, spacing: spacing, scrollDirection: scrollDirection, preferences: preferences)
let (alignments, gridHeight) = sut.alignmentsAndGridHeight(columns: columns, spacing: spacing, scrollDirection: scrollDirection, preferences: preferences)
// Then
XCTAssertEqual(expected, result, line: line)
XCTAssertEqual(expectedAlignments, alignments, line: line)
XCTAssertEqual(expectedGridHeight, gridHeight, line: line)
}
}

func test_calculateAlignmentGuides_withoutSpacingAndHorizontalScroll() {
func test_alignmentsAndGridHeight_withoutSpacingAndHorizontalScroll() {
// Given
let height = 40
let spacing: CGFloat = 0
Expand Down Expand Up @@ -215,18 +218,63 @@ class WaterfallGridTests: XCTestCase {
4: CGPoint(x: -80, y: -40)
]

let testCases: [ ([AnyHashable : CGPoint], Int, UInt) ] = [
// expected | columns | line
(alignmentsOneColumn, 1, #line),
(alignmentsTwoColumns, 2, #line),
(alignmentsThreeColumns, 3, #line)
let testCases: [ ([AnyHashable : CGPoint], CGFloat, Int, UInt) ] = [
// expectedAlignments | expectedGridHeight | columns | line
(alignmentsOneColumn, 390.0, 1, #line),
(alignmentsTwoColumns, 220.0, 2, #line),
(alignmentsThreeColumns, 180.0, 3, #line)
]

for (expected, columns, line) in testCases {
for (expectedAlignments, expectedGridHeight, columns, line) in testCases {
// When
let result = sut.calculateAlignmentGuides(columns: columns, spacing: spacing, scrollDirection: scrollDirection, preferences: preferences)
let (alignments, gridHeight) = sut.alignmentsAndGridHeight(columns: columns, spacing: spacing, scrollDirection: scrollDirection, preferences: preferences)
// Then
XCTAssertEqual(expected, result, line: line)
XCTAssertEqual(expectedAlignments, alignments, line: line)
XCTAssertEqual(expectedGridHeight, gridHeight, line: line)
}
}

func test_alignmentsAndGridHeight_emptyPreferencces_withSpacingAndVerticalScroll() {
// Given
let spacing: CGFloat = 8
let scrollDirection = Axis.Set.vertical
let preferences: [ElementPreferenceData] = []

let testCases: [ ([AnyHashable : CGPoint], CGFloat, Int, UInt) ] = [
// expectedAlignments | expectedGridHeight | columns | line
([:], 0.0, 1, #line),
([:], 0.0, 2, #line),
([:], 0.0, 3, #line)
]

for (expectedAlignments, expectedGridHeight, columns, line) in testCases {
// When
let (alignments, gridHeight) = sut.alignmentsAndGridHeight(columns: columns, spacing: spacing, scrollDirection: scrollDirection, preferences: preferences)
// Then
XCTAssertEqual(expectedAlignments, alignments, line: line)
XCTAssertEqual(expectedGridHeight, gridHeight, line: line)
}
}

func test_alignmentsAndGridHeight_emptyPreferencces_withoutSpacingAndVerticalScroll() {
// Given
let spacing: CGFloat = 0
let scrollDirection = Axis.Set.vertical
let preferences: [ElementPreferenceData] = []

let testCases: [ ([AnyHashable : CGPoint], CGFloat, Int, UInt) ] = [
// expectedAlignments | expectedGridHeight | columns | line
([:], 0.0, 1, #line),
([:], 0.0, 2, #line),
([:], 0.0, 3, #line)
]

for (expectedAlignments, expectedGridHeight, columns, line) in testCases {
// When
let (alignments, gridHeight) = sut.alignmentsAndGridHeight(columns: columns, spacing: spacing, scrollDirection: scrollDirection, preferences: preferences)
// Then
XCTAssertEqual(expectedAlignments, alignments, line: line)
XCTAssertEqual(expectedGridHeight, gridHeight, line: line)
}
}

Expand Down

0 comments on commit 22b9078

Please sign in to comment.