Skip to content
This repository was archived by the owner on Dec 27, 2020. It is now read-only.

Commit 07e2536

Browse files
committed
default grid style
1 parent 76a06be commit 07e2536

File tree

7 files changed

+106
-39
lines changed

7 files changed

+106
-39
lines changed

Examples/GridExamples iOS/ContentView.swift

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,38 +5,46 @@ struct ContentView: View {
55

66
var body: some View {
77
TabView(selection: $selection) {
8-
OneColumnLayoutView()
8+
AutoColumnsLayoutView()
99
.tabItem {
1010
VStack {
11-
Image(systemName: "rectangle.grid.1x2.fill")
12-
Text("One Column")
11+
Image(systemName: "square.grid.3x2.fill")
12+
Text("Auto Columns")
1313
}
1414
}
1515
.tag(0)
16-
AutoColumnLayoutView()
16+
FixedColumnsLayoutView()
1717
.tabItem {
1818
VStack {
19-
Image(systemName: "square.grid.3x2.fill")
20-
Text("Auto Column")
19+
Image(systemName: "rectangle.split.3x3.fill")
20+
Text("Fixed Columns")
2121
}
2222
}
2323
.tag(1)
24+
SingleColumnLayoutView()
25+
.tabItem {
26+
VStack {
27+
Image(systemName: "rectangle.grid.1x2.fill")
28+
Text("One Column")
29+
}
30+
}
31+
.tag(2)
2432
PerformanceLayoutView()
2533
.tabItem {
2634
VStack {
2735
Image(systemName: "square.grid.4x3.fill")
2836
Text("Performance")
2937
}
3038
}
31-
.tag(2)
39+
.tag(3)
3240
BuilderLayoutView()
3341
.tabItem {
3442
VStack {
3543
Image(systemName: "rectangle.3.offgrid.fill")
3644
Text("Builder")
3745
}
3846
}
39-
.tag(3)
47+
.tag(4)
4048
}
4149
.accentColor(.purple)
4250
}

Examples/GridExamples.xcodeproj/project.pbxproj

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
FA61E94F2312FE6D006A5B6B /* SingleColumnLayoutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA61E94E2312FE6D006A5B6B /* SingleColumnLayoutView.swift */; };
11+
FA61E9502312FE6D006A5B6B /* SingleColumnLayoutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA61E94E2312FE6D006A5B6B /* SingleColumnLayoutView.swift */; };
12+
FA61E9522312FF0F006A5B6B /* FixedColumnsLayoutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA61E9512312FF0F006A5B6B /* FixedColumnsLayoutView.swift */; };
13+
FA61E9532312FF0F006A5B6B /* FixedColumnsLayoutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA61E9512312FF0F006A5B6B /* FixedColumnsLayoutView.swift */; };
1014
FA6ED893231090FF00651DD9 /* BuilderLayoutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA6ED892231090FF00651DD9 /* BuilderLayoutView.swift */; };
1115
FA6ED894231090FF00651DD9 /* BuilderLayoutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA6ED892231090FF00651DD9 /* BuilderLayoutView.swift */; };
1216
FA902115230B32EA00BF9341 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA902114230B32EA00BF9341 /* AppDelegate.swift */; };
@@ -26,15 +30,15 @@
2630
FA902162230B379D00BF9341 /* Color+Random.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA902160230B379D00BF9341 /* Color+Random.swift */; };
2731
FA902164230B389900BF9341 /* Card.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA902163230B389900BF9341 /* Card.swift */; };
2832
FA902165230B389900BF9341 /* Card.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA902163230B389900BF9341 /* Card.swift */; };
29-
FA902167230B398200BF9341 /* OneColumnLayoutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA902166230B398200BF9341 /* OneColumnLayoutView.swift */; };
30-
FA902168230B398200BF9341 /* OneColumnLayoutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA902166230B398200BF9341 /* OneColumnLayoutView.swift */; };
31-
FA90216A230B39C800BF9341 /* AutoColumnLayoutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA902169230B39C800BF9341 /* AutoColumnLayoutView.swift */; };
32-
FA90216B230B39C800BF9341 /* AutoColumnLayoutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA902169230B39C800BF9341 /* AutoColumnLayoutView.swift */; };
33+
FA90216A230B39C800BF9341 /* AutoColumnsLayoutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA902169230B39C800BF9341 /* AutoColumnsLayoutView.swift */; };
34+
FA90216B230B39C800BF9341 /* AutoColumnsLayoutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA902169230B39C800BF9341 /* AutoColumnsLayoutView.swift */; };
3335
FA90216D230B3EC100BF9341 /* PerformanceLayoutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA90216C230B3EC100BF9341 /* PerformanceLayoutView.swift */; };
3436
FA90216E230B3EC100BF9341 /* PerformanceLayoutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA90216C230B3EC100BF9341 /* PerformanceLayoutView.swift */; };
3537
/* End PBXBuildFile section */
3638

3739
/* Begin PBXFileReference section */
40+
FA61E94E2312FE6D006A5B6B /* SingleColumnLayoutView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleColumnLayoutView.swift; sourceTree = "<group>"; };
41+
FA61E9512312FF0F006A5B6B /* FixedColumnsLayoutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FixedColumnsLayoutView.swift; sourceTree = "<group>"; };
3842
FA6ED892231090FF00651DD9 /* BuilderLayoutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BuilderLayoutView.swift; sourceTree = "<group>"; };
3943
FA6ED895231197C600651DD9 /* GridExamples iOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "GridExamples iOS.entitlements"; sourceTree = "<group>"; };
4044
FA902111230B32EA00BF9341 /* GridExamples iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "GridExamples iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -56,8 +60,7 @@
5660
FA902155230B341D00BF9341 /* GridExamples_macOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = GridExamples_macOS.entitlements; sourceTree = "<group>"; };
5761
FA902160230B379D00BF9341 /* Color+Random.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Color+Random.swift"; sourceTree = "<group>"; };
5862
FA902163230B389900BF9341 /* Card.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Card.swift; sourceTree = "<group>"; };
59-
FA902166230B398200BF9341 /* OneColumnLayoutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OneColumnLayoutView.swift; sourceTree = "<group>"; };
60-
FA902169230B39C800BF9341 /* AutoColumnLayoutView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AutoColumnLayoutView.swift; sourceTree = "<group>"; };
63+
FA902169230B39C800BF9341 /* AutoColumnsLayoutView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AutoColumnsLayoutView.swift; sourceTree = "<group>"; };
6164
FA90216C230B3EC100BF9341 /* PerformanceLayoutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PerformanceLayoutView.swift; sourceTree = "<group>"; };
6265
FA90216F230B4AC300BF9341 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = "<group>"; };
6366
/* End PBXFileReference section */
@@ -159,8 +162,9 @@
159162
FA90215C230B354900BF9341 /* GridExamples */ = {
160163
isa = PBXGroup;
161164
children = (
162-
FA902166230B398200BF9341 /* OneColumnLayoutView.swift */,
163-
FA902169230B39C800BF9341 /* AutoColumnLayoutView.swift */,
165+
FA902169230B39C800BF9341 /* AutoColumnsLayoutView.swift */,
166+
FA61E9512312FF0F006A5B6B /* FixedColumnsLayoutView.swift */,
167+
FA61E94E2312FE6D006A5B6B /* SingleColumnLayoutView.swift */,
164168
FA90216C230B3EC100BF9341 /* PerformanceLayoutView.swift */,
165169
FA6ED892231090FF00651DD9 /* BuilderLayoutView.swift */,
166170
FA902160230B379D00BF9341 /* Color+Random.swift */,
@@ -279,30 +283,32 @@
279283
isa = PBXSourcesBuildPhase;
280284
buildActionMask = 2147483647;
281285
files = (
286+
FA61E94F2312FE6D006A5B6B /* SingleColumnLayoutView.swift in Sources */,
282287
FA902115230B32EA00BF9341 /* AppDelegate.swift in Sources */,
283288
FA90216D230B3EC100BF9341 /* PerformanceLayoutView.swift in Sources */,
289+
FA61E9522312FF0F006A5B6B /* FixedColumnsLayoutView.swift in Sources */,
284290
FA902164230B389900BF9341 /* Card.swift in Sources */,
285291
FA6ED893231090FF00651DD9 /* BuilderLayoutView.swift in Sources */,
286292
FA902117230B32EA00BF9341 /* SceneDelegate.swift in Sources */,
287-
FA902167230B398200BF9341 /* OneColumnLayoutView.swift in Sources */,
288293
FA902119230B32EA00BF9341 /* ContentView.swift in Sources */,
289294
FA902161230B379D00BF9341 /* Color+Random.swift in Sources */,
290-
FA90216A230B39C800BF9341 /* AutoColumnLayoutView.swift in Sources */,
295+
FA90216A230B39C800BF9341 /* AutoColumnsLayoutView.swift in Sources */,
291296
);
292297
runOnlyForDeploymentPostprocessing = 0;
293298
};
294299
FA902142230B341C00BF9341 /* Sources */ = {
295300
isa = PBXSourcesBuildPhase;
296301
buildActionMask = 2147483647;
297302
files = (
303+
FA61E9502312FE6D006A5B6B /* SingleColumnLayoutView.swift in Sources */,
298304
FA902162230B379D00BF9341 /* Color+Random.swift in Sources */,
299305
FA90214B230B341C00BF9341 /* ContentView.swift in Sources */,
300306
FA6ED894231090FF00651DD9 /* BuilderLayoutView.swift in Sources */,
307+
FA61E9532312FF0F006A5B6B /* FixedColumnsLayoutView.swift in Sources */,
301308
FA90216E230B3EC100BF9341 /* PerformanceLayoutView.swift in Sources */,
302309
FA902165230B389900BF9341 /* Card.swift in Sources */,
303310
FA902149230B341C00BF9341 /* AppDelegate.swift in Sources */,
304-
FA902168230B398200BF9341 /* OneColumnLayoutView.swift in Sources */,
305-
FA90216B230B39C800BF9341 /* AutoColumnLayoutView.swift in Sources */,
311+
FA90216B230B39C800BF9341 /* AutoColumnsLayoutView.swift in Sources */,
306312
);
307313
runOnlyForDeploymentPostprocessing = 0;
308314
};
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
11
import SwiftUI
22
import Grid
33

4-
struct AutoColumnLayoutView: View {
4+
struct AutoColumnsLayoutView: View {
55
var body: some View {
66
Grid(0...100) { number in
77
Card(title: "\(number)")
88
}
99
.padding()
10-
.gridStyle(FixedColumnsGridStyle(columns: 5, itemHeight: 100))
1110
}
1211
}
1312

1413
#if DEBUG
1514
struct AutoColumnsGridView_Previews: PreviewProvider {
1615
static var previews: some View {
17-
AutoColumnLayoutView()
16+
AutoColumnsLayoutView()
1817
}
1918
}
2019
#endif
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import SwiftUI
2+
import Grid
3+
4+
struct FixedColumnsLayoutView: View {
5+
var body: some View {
6+
Grid(0...100) { number in
7+
Card(title: "\(number)")
8+
}
9+
.padding()
10+
.gridStyle(FixedColumnsGridStyle(columns: 5, itemHeight: 100))
11+
}
12+
}
13+
14+
struct FixedColumnsLayoutView_Previews: PreviewProvider {
15+
static var previews: some View {
16+
FixedColumnsLayoutView()
17+
}
18+
}

Examples/GridExamples/PerformanceLayoutView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ import Grid
33

44
struct PerformanceLayoutView: View {
55
var body: some View {
6-
//, minItemWidth: 20, itemHeight: 20)
76
Grid(0...5000) { number in
87
Rectangle()
98
.foregroundColor(.random)
109
}
10+
.gridStyle(DefaultGridStyle(minItemWidth: 16, itemHeight: 16, spacing: 0))
1111
}
1212
}
1313

Examples/GridExamples/OneColumnLayoutView.swift renamed to Examples/GridExamples/SingleColumnLayoutView.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import SwiftUI
22
import Grid
33

4-
struct OneColumnLayoutView: View {
4+
struct SingleColumnLayoutView: View {
55
var body: some View {
66
GeometryReader { geometry in
77
///Grid(0...100, minItemWidth: geometry.size.width, itemHeight: 300) { number in
@@ -17,7 +17,7 @@ struct OneColumnLayoutView: View {
1717
#if DEBUG
1818
struct OneColumnLayoutView_Previews: PreviewProvider {
1919
static var previews: some View {
20-
OneColumnLayoutView()
20+
SingleColumnLayoutView()
2121
}
2222
}
2323
#endif

Sources/Grid/DefaultGridStyle.swift

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,24 @@ import SwiftUI
55
public struct DefaultGridStyle: GridStyle {
66
public var padding = EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0)
77

8-
let minItemWidth: CGFloat = 100
9-
let itemHeight: CGFloat = 100
10-
let vSpacing: CGFloat = 8
11-
let hSpacing: CGFloat = 8
8+
let minItemWidth: CGFloat
9+
let itemHeight: CGFloat
10+
let vSpacing: CGFloat
11+
let hSpacing: CGFloat
1212

13-
public init() {}
13+
public init(minItemWidth: CGFloat = 160, itemHeight: CGFloat = 160, spacing: CGFloat = 8) {
14+
self.minItemWidth = minItemWidth
15+
self.itemHeight = itemHeight
16+
self.vSpacing = spacing
17+
self.hSpacing = spacing
18+
}
19+
20+
public init(minItemWidth: CGFloat = 160, itemHeight: CGFloat = 160, hSpacing: CGFloat = 8, vSpacing: CGFloat = 8) {
21+
self.minItemWidth = minItemWidth
22+
self.itemHeight = itemHeight
23+
self.hSpacing = hSpacing
24+
self.vSpacing = vSpacing
25+
}
1426

1527
public func frameHeight(at index: Int, with geometry: GeometryProxy, itemsCount: Int) -> CGFloat? {
1628
self.itemHeight
@@ -26,12 +38,21 @@ public struct DefaultGridStyle: GridStyle {
2638
minItemWidth: self.minItemWidth,
2739
itemHeight: self.itemHeight,
2840
padding: self.padding,
29-
hSpacing: self.hSpacing
41+
hSpacing: self.hSpacing,
42+
vSpacing: self.vSpacing
3043
)
3144
}
3245

3346
public func gridHeight(with geometry: GeometryProxy, itemsCount: Int) -> CGFloat {
34-
self.gridHeight(with: geometry, itemsCount: itemsCount, minItemWidth: self.minItemWidth, itemHeight: self.itemHeight, padding: self.padding, hSpacing: self.hSpacing)
47+
self.gridHeight(
48+
with: geometry,
49+
itemsCount: itemsCount,
50+
minItemWidth: self.minItemWidth,
51+
itemHeight: self.itemHeight,
52+
padding: self.padding,
53+
hSpacing: self.hSpacing,
54+
vSpacing: self.vSpacing
55+
)
3556
}
3657

3758

@@ -40,27 +61,42 @@ public struct DefaultGridStyle: GridStyle {
4061
return geometry.size.width - horizontalPadding
4162
}
4263

43-
@inlinable func position(at index: Int, with geometry: GeometryProxy, minItemWidth: CGFloat, itemHeight: CGFloat, padding: EdgeInsets, hSpacing: CGFloat) -> CGPoint {
64+
@inlinable func position(at index: Int, with geometry: GeometryProxy, minItemWidth: CGFloat, itemHeight: CGFloat, padding: EdgeInsets, hSpacing: CGFloat, vSpacing: CGFloat) -> CGPoint {
4465
let availableWidth = self.availableWidth(with: geometry, padding: padding, hSpacing: hSpacing)
4566
let columnCount = Int(availableWidth / minItemWidth)
4667
let row = index / max(1, columnCount)
4768
let itemIndexAtRow = index % max(1, columnCount)
4869
let itemWidth = self.itemWidth(for: geometry, minItemWidth: minItemWidth, padding: padding, hSpacing: hSpacing)
49-
let x = ((itemWidth / 2) + CGFloat(itemIndexAtRow) * itemWidth) + padding.leading
50-
let y = ((itemHeight / 2) + CGFloat(row) * itemHeight) + padding.top
70+
let hSpacingForItem = CGFloat(itemIndexAtRow) * hSpacing
71+
let x = ((itemWidth / 2) + CGFloat(itemIndexAtRow) * itemWidth) + padding.leading + hSpacingForItem
72+
let y = ((itemHeight / 2) + CGFloat(row) * itemHeight) + padding.top + (CGFloat(row) * vSpacing)
5173
return CGPoint(x: x, y: y)
5274
}
5375

5476
@inlinable func itemWidth(for geometry: GeometryProxy, minItemWidth: CGFloat, padding: EdgeInsets, hSpacing: CGFloat) -> CGFloat {
5577
let availableWidth = self.availableWidth(with: geometry, padding: padding, hSpacing: hSpacing)
56-
return availableWidth / max(1.0, availableWidth / minItemWidth).rounded(.down)
78+
let columnCount = Int(availableWidth / minItemWidth)
79+
80+
for columns in (0...columnCount).reversed() {
81+
let suggestedItemWidth = self.itemWidth(for: geometry, columns: columns, padding: padding, hSpacing: hSpacing)
82+
if (suggestedItemWidth * CGFloat(columns)) + (CGFloat(columns - 1) * hSpacing) <= availableWidth {
83+
return suggestedItemWidth
84+
}
85+
}
86+
return availableWidth
87+
}
88+
89+
@inlinable func itemWidth(for geometry: GeometryProxy, columns: Int, padding: EdgeInsets, hSpacing: CGFloat) -> CGFloat {
90+
let availableWidth = self.availableWidth(with: geometry, padding: padding, hSpacing: hSpacing)
91+
let usableWidth = availableWidth - (CGFloat(columns - 1) * hSpacing)
92+
return usableWidth / CGFloat(columns)
5793
}
5894

59-
@inlinable func gridHeight(with geometry: GeometryProxy, itemsCount: Int, minItemWidth: CGFloat, itemHeight: CGFloat, padding: EdgeInsets, hSpacing: CGFloat) -> CGFloat {
95+
@inlinable func gridHeight(with geometry: GeometryProxy, itemsCount: Int, minItemWidth: CGFloat, itemHeight: CGFloat, padding: EdgeInsets, hSpacing: CGFloat, vSpacing: CGFloat) -> CGFloat {
6096
let availableWidth = self.availableWidth(with: geometry, padding: padding, hSpacing: hSpacing)
6197
let columnCount = Int(availableWidth / minItemWidth)
6298
let rowCount = Int((CGFloat(itemsCount) / max(1.0, CGFloat(columnCount))).rounded(.up))
6399
let verticalPadding = padding.top + padding.bottom
64-
return CGFloat(rowCount) * itemHeight + verticalPadding
100+
return CGFloat(rowCount) * itemHeight + verticalPadding + (CGFloat(rowCount - 1) * vSpacing)
65101
}
66102
}

0 commit comments

Comments
 (0)