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

Commit bd9a76f

Browse files
authored
Item size preferences (#22)
* item size preferences * readme
1 parent 8974880 commit bd9a76f

File tree

8 files changed

+98
-11
lines changed

8 files changed

+98
-11
lines changed

Examples/GridExamples/AutoColumnsLayoutView.swift

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

44
struct AutoColumnsLayoutView: View {
5+
@State var selection: Int = 0
6+
57
var body: some View {
6-
Grid(0...100) { number in
8+
Grid(0..<100) { number in
79
Card(title: "\(number)")
10+
.onTapGesture {
11+
self.selection = number
12+
}
813
}
914
.padding()
15+
.overlayPreferenceValue(GridItemPreferences.Key.self) { preferences in
16+
GeometryReader { geometry in
17+
RoundedRectangle(cornerRadius: 16)
18+
.strokeBorder(lineWidth: 4)
19+
.foregroundColor(.white)
20+
.frame(
21+
width: geometry[preferences[self.selection].bounds].size.width,
22+
height: geometry[preferences[self.selection].bounds].size.height
23+
)
24+
.offset(
25+
x: geometry[preferences[self.selection].bounds].minX,
26+
y: geometry[preferences[self.selection].bounds].minY
27+
)
28+
.animation(.spring())
29+
}
30+
}
1031
}
1132
}
1233

README.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,40 @@ Grid(0...100) { number in
7373
- watchOS 6+
7474
- Xcode 11.0+
7575

76+
## Preferences
77+
Get item size and position with preferences
78+
```swift
79+
struct CardsView: View {
80+
@State var selection: Int = 0
81+
82+
var body: some View {
83+
Grid(0..<100) { number in
84+
Card(title: "\(number)")
85+
.onTapGesture {
86+
self.selection = number
87+
}
88+
}
89+
.padding()
90+
.overlayPreferenceValue(GridItemPreferences.Key.self) { preferences in
91+
GeometryReader { geometry in
92+
RoundedRectangle(cornerRadius: 16)
93+
.strokeBorder(lineWidth: 4)
94+
.foregroundColor(.white)
95+
.frame(
96+
width: geometry[preferences[self.selection].bounds].size.width,
97+
height: geometry[preferences[self.selection].bounds].size.height
98+
)
99+
.offset(
100+
x: geometry[preferences[self.selection].bounds].minX,
101+
y: geometry[preferences[self.selection].bounds].minY
102+
)
103+
.animation(.spring())
104+
}
105+
}
106+
}
107+
}
108+
```
109+
76110
## Version 1.0.0
77111
Stable version will be released as soon as XCode 11 GM becomes available. We will strictly follow semantic versioning moving forward.
78112

Sources/Grid/AutoColumnsGridStyle.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ public struct AutoColumnsGridStyle: GridStyle {
2323
self.vSpacing = vSpacing
2424
}
2525

26-
public func frameHeight(at index: Int, with geometry: GeometryProxy, itemsCount: Int) -> CGFloat? {
26+
public func frameHeight(at index: Int, with geometry: GeometryProxy, itemsCount: Int) -> CGFloat {
2727
self.itemHeight
2828
}
29-
public func frameWidth(at index: Int, with geometry: GeometryProxy, itemsCount: Int) -> CGFloat? {
29+
public func frameWidth(at index: Int, with geometry: GeometryProxy, itemsCount: Int) -> CGFloat {
3030
self.itemWidth(for: geometry, minItemWidth: self.minItemWidth, padding: self.padding, hSpacing: self.hSpacing)
3131
}
3232

Sources/Grid/FixedColumnsGridStyle.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ public struct FixedColumnsGridStyle: GridStyle {
2323
self.vSpacing = vSpacing
2424
}
2525

26-
public func frameHeight(at index: Int, with geometry: GeometryProxy, itemsCount: Int) -> CGFloat? {
26+
public func frameHeight(at index: Int, with geometry: GeometryProxy, itemsCount: Int) -> CGFloat {
2727
self.itemHeight
2828
}
29-
public func frameWidth(at index: Int, with geometry: GeometryProxy, itemsCount: Int) -> CGFloat? {
29+
public func frameWidth(at index: Int, with geometry: GeometryProxy, itemsCount: Int) -> CGFloat {
3030
self.itemWidth(for: geometry, columns: self.columns, padding: self.padding, hSpacing: self.hSpacing)
3131
}
3232

Sources/Grid/Grid+Style.swift

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,24 @@ import SwiftUI
44
public protocol GridStyle {
55
var padding: EdgeInsets { get set }
66

7-
func frameHeight(at index: Int, with geometry: GeometryProxy, itemsCount: Int) -> CGFloat?
8-
func frameWidth(at index: Int, with geometry: GeometryProxy, itemsCount: Int) -> CGFloat?
7+
func frameHeight(at index: Int, with geometry: GeometryProxy, itemsCount: Int) -> CGFloat
8+
func frameWidth(at index: Int, with geometry: GeometryProxy, itemsCount: Int) -> CGFloat
99
func position(at index: Int, with geometry: GeometryProxy, itemsCount: Int) -> CGPoint
1010
func gridHeight(with geometry: GeometryProxy, itemsCount: Int) -> CGFloat
11+
12+
func itemRect(at index: Int, with geometry: GeometryProxy, itemsCount: Int) -> CGRect
13+
}
14+
15+
public extension GridStyle {
16+
/// Translated from center origin to leading.
17+
@inlinable func itemRect(at index: Int, with geometry: GeometryProxy, itemsCount: Int) -> CGRect {
18+
CGRect(
19+
x: self.position(at: index, with: geometry, itemsCount: itemsCount).x - geometry.size.width / 2,
20+
y: self.position(at: index, with: geometry, itemsCount: itemsCount).y - geometry.size.height / 2,
21+
width: self.frameWidth(at: index, with: geometry, itemsCount: itemsCount),
22+
height: self.frameHeight(at: index, with: geometry, itemsCount: itemsCount)
23+
)
24+
}
1125
}
1226

1327

Sources/Grid/Grid.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,13 @@ public struct Grid<Content> : View where Content : View {
1414
self.items[index]
1515
.frame(
1616
width: self.style.frameWidth(at: index, with: geometry, itemsCount: self.items.count),
17-
height: self.style.frameHeight(at: index, with: geometry, itemsCount: self.items.count),
18-
alignment: Alignment(horizontal: .leading, vertical: .top)
17+
height: self.style.frameHeight(at: index, with: geometry, itemsCount: self.items.count)
1918
)
19+
2020
.position(self.style.position(at: index, with: geometry, itemsCount: self.items.count))
21+
.anchorPreference(key: GridItemPreferences.Key.self, value: .rect(self.style.itemRect(at: index, with: geometry, itemsCount: self.items.count))) {
22+
[GridItemPreferences(index: index, bounds: $0)]
23+
}
2124
}
2225
}
2326
.frame(
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import Foundation
2+
import SwiftUI
3+
4+
public struct GridItemPreferences {
5+
public struct Key: PreferenceKey {
6+
public static var defaultValue: [GridItemPreferences] = []
7+
8+
public static func reduce(value: inout [GridItemPreferences], nextValue: () -> [GridItemPreferences]) {
9+
value.append(contentsOf: nextValue())
10+
}
11+
}
12+
13+
public let index: Int
14+
public let bounds: Anchor<CGRect>
15+
}

Sources/Grid/SingleColumnGridStyle.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ public struct SingleColumnGridStyle: GridStyle {
1212
self.spacing = spacing
1313
}
1414

15-
public func frameHeight(at index: Int, with geometry: GeometryProxy, itemsCount: Int) -> CGFloat? {
15+
public func frameHeight(at index: Int, with geometry: GeometryProxy, itemsCount: Int) -> CGFloat {
1616
itemHeight
1717
}
18-
public func frameWidth(at index: Int, with geometry: GeometryProxy, itemsCount: Int) -> CGFloat? {
18+
public func frameWidth(at index: Int, with geometry: GeometryProxy, itemsCount: Int) -> CGFloat {
1919
geometry.size.width - (padding.leading + padding.trailing)
2020
}
2121

0 commit comments

Comments
 (0)