Skip to content

Commit 0a3a94b

Browse files
author
Trent Guillory
committed
Wrapped up index callback and center spacing.
1 parent 6adddf3 commit 0a3a94b

File tree

15 files changed

+576
-170
lines changed

15 files changed

+576
-170
lines changed

SnapToScrollDemo/SnapToScrollDemo.xcodeproj/project.pbxproj

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
840130AF26DFB8DD00E4A8A3 /* GettingStartedModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 840130AE26DFB8DC00E4A8A3 /* GettingStartedModel.swift */; };
11+
840130B126DFB93400E4A8A3 /* GettingStartedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 840130B026DFB93400E4A8A3 /* GettingStartedView.swift */; };
12+
840130B326DFC27700E4A8A3 /* Example3ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 840130B226DFC27700E4A8A3 /* Example3ContentView.swift */; };
13+
840130B526DFC2FB00E4A8A3 /* Example2ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 840130B426DFC2FB00E4A8A3 /* Example2ContentView.swift */; };
14+
840130B726DFC33100E4A8A3 /* Example1ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 840130B626DFC33100E4A8A3 /* Example1ContentView.swift */; };
1015
841B0F8326DD39A4008A436B /* TripTupleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 841B0F8226DD39A4008A436B /* TripTupleView.swift */; };
1116
84B568D926DD271000D37CF2 /* TagView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B568D826DD271000D37CF2 /* TagView.swift */; };
1217
84B568DB26DD309400D37CF2 /* Example1HeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B568DA26DD309400D37CF2 /* Example1HeaderView.swift */; };
@@ -23,6 +28,11 @@
2328
/* End PBXBuildFile section */
2429

2530
/* Begin PBXFileReference section */
31+
840130AE26DFB8DC00E4A8A3 /* GettingStartedModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GettingStartedModel.swift; sourceTree = "<group>"; };
32+
840130B026DFB93400E4A8A3 /* GettingStartedView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GettingStartedView.swift; sourceTree = "<group>"; };
33+
840130B226DFC27700E4A8A3 /* Example3ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Example3ContentView.swift; sourceTree = "<group>"; };
34+
840130B426DFC2FB00E4A8A3 /* Example2ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Example2ContentView.swift; sourceTree = "<group>"; };
35+
840130B626DFC33100E4A8A3 /* Example1ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Example1ContentView.swift; sourceTree = "<group>"; };
2636
841B0F8226DD39A4008A436B /* TripTupleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TripTupleView.swift; sourceTree = "<group>"; };
2737
84B568D826DD271000D37CF2 /* TagView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagView.swift; sourceTree = "<group>"; };
2838
84B568DA26DD309400D37CF2 /* Example1HeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Example1HeaderView.swift; sourceTree = "<group>"; };
@@ -52,9 +62,20 @@
5262
/* End PBXFrameworksBuildPhase section */
5363

5464
/* Begin PBXGroup section */
65+
840130AD26DFB8C800E4A8A3 /* Example3 */ = {
66+
isa = PBXGroup;
67+
children = (
68+
840130B226DFC27700E4A8A3 /* Example3ContentView.swift */,
69+
840130AE26DFB8DC00E4A8A3 /* GettingStartedModel.swift */,
70+
840130B026DFB93400E4A8A3 /* GettingStartedView.swift */,
71+
);
72+
path = Example3;
73+
sourceTree = "<group>";
74+
};
5575
84B568D626DD26A800D37CF2 /* Example1 */ = {
5676
isa = PBXGroup;
5777
children = (
78+
840130B626DFC33100E4A8A3 /* Example1ContentView.swift */,
5879
84C99CD726D99BA100C1D5C4 /* TagModel.swift */,
5980
84B568D826DD271000D37CF2 /* TagView.swift */,
6081
84B568DA26DD309400D37CF2 /* Example1HeaderView.swift */,
@@ -68,6 +89,7 @@
6889
84B568DD26DD351900D37CF2 /* TripModel.swift */,
6990
84B568DF26DD37A600D37CF2 /* TripView.swift */,
7091
841B0F8226DD39A4008A436B /* TripTupleView.swift */,
92+
840130B426DFC2FB00E4A8A3 /* Example2ContentView.swift */,
7193
);
7294
path = "Example 2";
7395
sourceTree = "<group>";
@@ -97,6 +119,7 @@
97119
84D9FA3526D9753600F87EF5 /* AppDelegate.swift */,
98120
84B568D626DD26A800D37CF2 /* Example1 */,
99121
84B568DC26DD311F00D37CF2 /* Example 2 */,
122+
840130AD26DFB8C800E4A8A3 /* Example3 */,
100123
84D9FA3726D9753600F87EF5 /* SceneDelegate.swift */,
101124
84D9FA3926D9753600F87EF5 /* ContentView.swift */,
102125
);
@@ -204,10 +227,15 @@
204227
files = (
205228
84B568DB26DD309400D37CF2 /* Example1HeaderView.swift in Sources */,
206229
84D9FA3626D9753600F87EF5 /* AppDelegate.swift in Sources */,
230+
840130AF26DFB8DD00E4A8A3 /* GettingStartedModel.swift in Sources */,
207231
841B0F8326DD39A4008A436B /* TripTupleView.swift in Sources */,
232+
840130B726DFC33100E4A8A3 /* Example1ContentView.swift in Sources */,
208233
84B568D926DD271000D37CF2 /* TagView.swift in Sources */,
234+
840130B326DFC27700E4A8A3 /* Example3ContentView.swift in Sources */,
209235
84B568E026DD37A600D37CF2 /* TripView.swift in Sources */,
236+
840130B526DFC2FB00E4A8A3 /* Example2ContentView.swift in Sources */,
210237
84B568DE26DD351900D37CF2 /* TripModel.swift in Sources */,
238+
840130B126DFB93400E4A8A3 /* GettingStartedView.swift in Sources */,
211239
84D9FA3826D9753600F87EF5 /* SceneDelegate.swift in Sources */,
212240
84D9FA3A26D9753600F87EF5 /* ContentView.swift in Sources */,
213241
84C99CD826D99BA100C1D5C4 /* TagModel.swift in Sources */,

SnapToScrollDemo/Sources/ContentView.swift

Lines changed: 11 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -5,58 +5,28 @@ import SwiftUI
55

66
struct ContentView: View {
77

8-
@State var items = [("one", 1), ("two", 2), ("three", 3), ("four", 4), ("five", 5), ("six", 6)]
9-
108
var body: some View {
119
VStack {
1210

1311
ScrollView {
1412

1513
VerticalSpace
1614

17-
VStack {
18-
19-
LargeHeader(text: "Example 1")
20-
21-
Example1HeaderView()
22-
23-
// Don't forget to attach GeometryReaderOverlay!
24-
HStackSnap(leadingOffset: 16) {
25-
26-
ForEach(TagModel.exampleModels) { viewModel in
27-
28-
TagView(viewModel: viewModel)
29-
.overlay(GeometryReaderOverlay(id: viewModel.id))
30-
}
31-
}.padding(.top, 4)
32-
}
15+
LargeHeader(text: "Example 1")
16+
17+
Example1ContentView()
3318

3419
VerticalSpace
3520

36-
VStack {
37-
38-
LargeHeader(text: "Example 2")
39-
40-
Text("Explore Nearby")
41-
.font(.system(size: 22, weight: .semibold, design: .rounded))
42-
.frame(maxWidth: .infinity, alignment: .leading)
43-
.padding([.top, .leading], 16)
44-
45-
HStackSnap(leadingOffset: 16) {
46-
47-
ForEach(TripTupleModel.exampleModels) { viewModel in
21+
LargeHeader(text: "Example 2")
22+
23+
Example2ContentView()
24+
25+
VerticalSpace
4826

49-
TripTupleView(viewModel: viewModel)
50-
.frame(maxWidth: 250)
51-
.overlay(GeometryReaderOverlay(id: viewModel.id))
52-
}
53-
} onSwipe: { index in
54-
55-
print(index)
56-
}
57-
.frame(height: 200)
58-
.padding(.top, 4)
59-
}
27+
LargeHeader(text: "Example 3")
28+
29+
Example3ContentView()
6030
}
6131
}
6232
.preferredColorScheme(.light)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import SwiftUI
2+
import SnapToScroll
3+
4+
// MARK: - Example2ContentView
5+
6+
struct Example2ContentView: View {
7+
var body: some View {
8+
9+
VStack {
10+
11+
Text("Explore Nearby")
12+
.font(.system(size: 22, weight: .semibold, design: .rounded))
13+
.frame(maxWidth: .infinity, alignment: .leading)
14+
.padding([.top, .leading], 16)
15+
16+
HStackSnap(alignment: .leading(16)) {
17+
18+
ForEach(TripTupleModel.exampleModels) { viewModel in
19+
20+
TripTupleView(viewModel: viewModel)
21+
.frame(maxWidth: 250)
22+
.snapAlignmentHelper(id: viewModel.id)
23+
}
24+
} onSwipe: { index in
25+
26+
print(index)
27+
}
28+
.frame(height: 130)
29+
.padding(.top, 4)
30+
}
31+
}
32+
}
33+
34+
// MARK: - Example2ContentView_Previews
35+
36+
struct Example2ContentView_Previews: PreviewProvider {
37+
static var previews: some View {
38+
Example2ContentView()
39+
}
40+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//
2+
// Example2ContentView.swift
3+
// Example2ContentView
4+
//
5+
// Created by Trent Guillory on 9/1/21.
6+
//
7+
8+
import SwiftUI
9+
import SnapToScroll
10+
11+
struct Example1ContentView: View {
12+
var body: some View {
13+
14+
VStack {
15+
16+
Example1HeaderView()
17+
18+
// Don't forget to attach snapAlignmentHelper!
19+
HStackSnap(alignment: .leading(16)) {
20+
21+
ForEach(TagModel.exampleModels) { viewModel in
22+
23+
TagView(viewModel: viewModel)
24+
.snapAlignmentHelper(id: viewModel.id)
25+
}
26+
}.padding(.top, 4)
27+
}
28+
}
29+
}
30+
31+
struct Example1ContentView_Previews: PreviewProvider {
32+
static var previews: some View {
33+
Example2ContentView()
34+
}
35+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//
2+
// Example3ContentView.swift
3+
// Example3ContentView
4+
//
5+
// Created by Trent Guillory on 9/1/21.
6+
//
7+
8+
import SnapToScroll
9+
import SwiftUI
10+
11+
struct Example3ContentView: View {
12+
13+
@State private var selectedGettingStartedIndex: Int = 0
14+
15+
var body: some View {
16+
17+
VStack {
18+
19+
Text("Getting Started")
20+
.font(.system(size: 22, weight: .semibold, design: .rounded))
21+
.foregroundColor(.white)
22+
.frame(maxWidth: .infinity, alignment: .leading)
23+
.padding([.top, .leading], 32)
24+
25+
HStackSnap(alignment: .center(32)) {
26+
27+
ForEach(GettingStartedModel.exampleModels) { viewModel in
28+
29+
GettingStartedView(selectedIndex: $selectedGettingStartedIndex, viewModel: viewModel)
30+
.snapAlignmentHelper(id: viewModel.id)
31+
}
32+
} onSwipe: { index in
33+
34+
selectedGettingStartedIndex = index
35+
}
36+
.frame(height: 200)
37+
.padding(.top, 4)
38+
}
39+
.padding([.top, .bottom], 64)
40+
.background(LinearGradient(colors: [Color("Cream"), Color("LightPink")], startPoint: .top, endPoint: .bottom))
41+
}
42+
}
43+
44+
struct Example3ContentView_Previews: PreviewProvider {
45+
static var previews: some View {
46+
Example3ContentView()
47+
}
48+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import Foundation
2+
3+
struct GettingStartedModel: Identifiable {
4+
5+
static let exampleModels: [GettingStartedModel] = [
6+
.init(id: 0, systemImage: "camera.aperture", title: "Snap a Pic", body: "We feature the viewfinder front and center in this throwback app."),
7+
.init(id: 1, systemImage: "camera.filters", title: "Filter it Up", body: "Add filters - from detailed colorization to film effects."),
8+
.init(id: 2, systemImage: "paperplane", title: "Send It", body: "Share your photos with your contacts. Or the entire world."),
9+
.init(id: 3, systemImage: "sparkles", title: "Be Awesome", body: "You're clearly already doing this. Just wanted to remind you. 😉")
10+
]
11+
12+
let id: Int
13+
let systemImage: String
14+
let title: String
15+
let body: String
16+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import SwiftUI
2+
3+
// MARK: - TagView
4+
5+
struct GettingStartedView: View {
6+
7+
@Binding var selectedIndex: Int
8+
9+
let viewModel: GettingStartedModel
10+
11+
var body: some View {
12+
13+
VStack(alignment: .leading) {
14+
15+
Image(systemName: viewModel.systemImage)
16+
.foregroundColor(isSelected ? Color("LightPink") : .gray)
17+
.font(.system(size: 32))
18+
.padding(.bottom, 2)
19+
20+
Text(viewModel.title)
21+
.fontWeight(.semibold)
22+
.foregroundColor(.black)
23+
.frame(maxWidth: .infinity, alignment: .leading)
24+
.padding(.bottom, 1)
25+
.opacity(0.8)
26+
27+
Text(viewModel.body)
28+
.foregroundColor(.black)
29+
.multilineTextAlignment(.leading)
30+
.opacity(0.8)
31+
}
32+
.padding()
33+
.background(Color.white)
34+
.cornerRadius(12)
35+
.opacity(isSelected ? 1 : 0.8)
36+
}
37+
38+
var isSelected: Bool {
39+
40+
return selectedIndex == viewModel.id
41+
}
42+
}
43+
44+
// MARK: - TagView_Previews
45+
46+
struct GettingStartedView_Previews: PreviewProvider {
47+
static var previews: some View {
48+
49+
GettingStartedView(selectedIndex: .constant(0), viewModel: GettingStartedModel.exampleModels.first!)
50+
}
51+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"colors" : [
3+
{
4+
"color" : {
5+
"color-space" : "srgb",
6+
"components" : {
7+
"alpha" : "1.000",
8+
"blue" : "0xB4",
9+
"green" : "0xD4",
10+
"red" : "0xDB"
11+
}
12+
},
13+
"idiom" : "universal"
14+
},
15+
{
16+
"appearances" : [
17+
{
18+
"appearance" : "luminosity",
19+
"value" : "dark"
20+
}
21+
],
22+
"color" : {
23+
"color-space" : "srgb",
24+
"components" : {
25+
"alpha" : "1.000",
26+
"blue" : "0.706",
27+
"green" : "0.831",
28+
"red" : "0.859"
29+
}
30+
},
31+
"idiom" : "universal"
32+
}
33+
],
34+
"info" : {
35+
"author" : "xcode",
36+
"version" : 1
37+
}
38+
}

0 commit comments

Comments
 (0)