Skip to content

Commit cbaf690

Browse files
committed
Upgrade "Framework Integration"
1 parent f11478a commit cbaf690

30 files changed

+1183
-142
lines changed

Framework-Integration/Assets.xcassets/AppIcon.appiconset/Contents.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,15 @@
3636
"scale" : "3x"
3737
},
3838
{
39-
"idiom" : "iphone",
4039
"size" : "60x60",
40+
"idiom" : "iphone",
41+
"filename" : "landmark_app_icon_120x120-1.png",
4142
"scale" : "2x"
4243
},
4344
{
44-
"idiom" : "iphone",
4545
"size" : "60x60",
46+
"idiom" : "iphone",
47+
"filename" : "landmark_app_icon_180x180.png",
4648
"scale" : "3x"
4749
},
4850
{
Loading
Loading

Framework-Integration/ContentView.swift

Lines changed: 0 additions & 22 deletions
This file was deleted.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
See LICENSE folder for this sample’s licensing information.
3+
4+
Abstract:
5+
A single line in the graph.
6+
*/
7+
8+
import SwiftUI
9+
10+
struct GraphCapsule: View {
11+
var index: Int
12+
var height: CGFloat
13+
var range: Range<Double>
14+
var overallRange: Range<Double>
15+
16+
var heightRatio: CGFloat {
17+
max(CGFloat(magnitude(of: range) / magnitude(of: overallRange)), 0.15)
18+
}
19+
20+
var offsetRatio: CGFloat {
21+
CGFloat((range.lowerBound - overallRange.lowerBound) / magnitude(of: overallRange))
22+
}
23+
24+
var animation: Animation {
25+
Animation.spring(dampingFraction: 0.5)
26+
.speed(2)
27+
.delay(0.03 * Double(index))
28+
}
29+
30+
var body: some View {
31+
Capsule()
32+
.fill(Color.white)
33+
.frame(height: height * heightRatio, alignment: .bottom)
34+
.offset(x: 0, y: height * -offsetRatio)
35+
.animation(animation)
36+
}
37+
}
38+
39+
struct GraphCapsule_Previews: PreviewProvider {
40+
static var previews: some View {
41+
GraphCapsule(index: 0, height: 150, range: 10..<50, overallRange: 0..<100)
42+
}
43+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
See LICENSE folder for this sample’s licensing information.
3+
4+
Abstract:
5+
A view that shows a badge for hiking.
6+
*/
7+
8+
import SwiftUI
9+
10+
struct HikeBadge: View {
11+
var name: String
12+
var body: some View {
13+
VStack(alignment: .center) {
14+
Badge()
15+
.frame(width: 300, height: 300)
16+
.scaleEffect(1.0 / 3.0)
17+
.frame(width: 100, height: 100)
18+
Text(name)
19+
.font(.caption)
20+
.accessibility(label: Text("Badge for \(name)."))
21+
}
22+
}
23+
}
24+
25+
struct HikeBadge_Previews: PreviewProvider {
26+
static var previews: some View {
27+
HikeBadge(name: "Preview Testing")
28+
}
29+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
See LICENSE folder for this sample’s licensing information.
3+
4+
Abstract:
5+
A view showing the details for a hike.
6+
*/
7+
8+
import SwiftUI
9+
10+
struct HikeDetail: View {
11+
let hike: Hike
12+
@State var dataToShow = \Hike.Observation.elevation
13+
14+
var buttons = [
15+
("Elevation", \Hike.Observation.elevation),
16+
("Heart Rate", \Hike.Observation.heartRate),
17+
("Pace", \Hike.Observation.pace),
18+
]
19+
20+
var body: some View {
21+
return VStack {
22+
HikeGraph(hike: hike, path: dataToShow)
23+
.frame(height: 200, alignment: .center)
24+
25+
HStack(spacing: 25) {
26+
ForEach(buttons, id: \.0) { value in
27+
Button(action: {
28+
self.dataToShow = value.1
29+
}) {
30+
Text(verbatim: value.0)
31+
.font(.system(size: 15))
32+
.foregroundColor(value.1 == self.dataToShow
33+
? Color.gray
34+
: Color.accentColor)
35+
.animation(nil)
36+
}
37+
}
38+
}
39+
}
40+
}
41+
}
42+
43+
struct HikeDetail_Previews: PreviewProvider {
44+
static var previews: some View {
45+
HikeDetail(hike: hikeData[0])
46+
}
47+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
See LICENSE folder for this sample’s licensing information.
3+
4+
Abstract:
5+
The elevation, heart rate, and pace of a hike plotted on a graph.
6+
*/
7+
8+
import SwiftUI
9+
10+
func rangeOfRanges<C: Collection>(_ ranges: C) -> Range<Double>
11+
where C.Element == Range<Double> {
12+
guard !ranges.isEmpty else { return 0..<0 }
13+
let low = ranges.lazy.map { $0.lowerBound }.min()!
14+
let high = ranges.lazy.map { $0.upperBound }.max()!
15+
return low..<high
16+
}
17+
18+
func magnitude(of range: Range<Double>) -> Double {
19+
return range.upperBound - range.lowerBound
20+
}
21+
22+
struct HikeGraph: View {
23+
var hike: Hike
24+
var path: KeyPath<Hike.Observation, Range<Double>>
25+
26+
var color: Color {
27+
switch path {
28+
case \.elevation:
29+
return .gray
30+
case \.heartRate:
31+
return Color(hue: 0, saturation: 0.5, brightness: 0.7)
32+
case \.pace:
33+
return Color(hue: 0.7, saturation: 0.4, brightness: 0.7)
34+
default:
35+
return .black
36+
}
37+
}
38+
39+
var body: some View {
40+
let data = hike.observations
41+
let overallRange = rangeOfRanges(data.lazy.map { $0[keyPath: self.path] })
42+
let maxMagnitude = data.map { magnitude(of: $0[keyPath: path]) }.max()!
43+
let heightRatio = 1 - CGFloat(maxMagnitude / magnitude(of: overallRange))
44+
45+
return GeometryReader { proxy in
46+
HStack(alignment: .bottom, spacing: proxy.size.width / 120) {
47+
ForEach(data.indices) { index in
48+
GraphCapsule(
49+
index: index,
50+
height: proxy.size.height,
51+
range: data[index][keyPath: self.path],
52+
overallRange: overallRange)
53+
.colorMultiply(self.color)
54+
}
55+
.offset(x: 0, y: proxy.size.height * heightRatio)
56+
}
57+
}
58+
}
59+
}
60+
61+
struct HikeGraph_Previews: PreviewProvider {
62+
static var previews: some View {
63+
Group {
64+
HikeGraph(hike: hikeData[0], path: \.elevation)
65+
.frame(height: 200)
66+
HikeGraph(hike: hikeData[0], path: \.heartRate)
67+
.frame(height: 200)
68+
HikeGraph(hike: hikeData[0], path: \.pace)
69+
.frame(height: 200)
70+
}
71+
}
72+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
See LICENSE folder for this sample’s licensing information.
3+
4+
Abstract:
5+
A view displaying inforamtion about a hike, including an elevation graph.
6+
*/
7+
8+
import SwiftUI
9+
10+
struct HikeView: View {
11+
var hike: Hike
12+
@State private var showDetail = false
13+
14+
var transition: AnyTransition {
15+
let insertion = AnyTransition.move(edge: .trailing)
16+
.combined(with: .opacity)
17+
let removal = AnyTransition.scale
18+
.combined(with: .opacity)
19+
return .asymmetric(insertion: insertion, removal: removal)
20+
}
21+
22+
var body: some View {
23+
VStack {
24+
HStack {
25+
HikeGraph(hike: hike, path: \.elevation)
26+
.frame(width: 50, height: 30)
27+
.animation(nil)
28+
29+
VStack(alignment: .leading) {
30+
Text(verbatim: hike.name)
31+
.font(.headline)
32+
Text(verbatim: hike.distanceText)
33+
}
34+
35+
Spacer()
36+
37+
Button(action: {
38+
withAnimation {
39+
self.showDetail.toggle()
40+
}
41+
}) {
42+
Image(systemName: "chevron.right.circle")
43+
.imageScale(.large)
44+
.rotationEffect(.degrees(showDetail ? 90 : 0))
45+
.scaleEffect(showDetail ? 1.5 : 1)
46+
.padding()
47+
}
48+
}
49+
50+
if showDetail {
51+
HikeDetail(hike: hike)
52+
.transition(transition)
53+
}
54+
}
55+
}
56+
}
57+
58+
struct HikeView_Previews: PreviewProvider {
59+
static var previews: some View {
60+
VStack {
61+
HikeView(hike: hikeData[0])
62+
.padding()
63+
Spacer()
64+
}
65+
}
66+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
See LICENSE folder for this sample’s licensing information.
3+
4+
Abstract:
5+
A view showing a scrollable list of landmarks.
6+
*/
7+
8+
import SwiftUI
9+
10+
struct CategoryRow: View {
11+
var categoryName: String
12+
var items: [Landmark]
13+
14+
var body: some View {
15+
VStack(alignment: .leading) {
16+
Text(self.categoryName)
17+
.font(.headline)
18+
.padding(.leading, 15)
19+
.padding(.top, 5)
20+
21+
ScrollView(.horizontal, showsIndicators: false) {
22+
HStack(alignment: .top, spacing: 0) {
23+
ForEach(self.items) { landmark in
24+
NavigationLink(
25+
destination: LandmarkDetail(
26+
landmark: landmark
27+
)
28+
) {
29+
CategoryItem(landmark: landmark)
30+
}
31+
}
32+
}
33+
}
34+
.frame(height: 185)
35+
}
36+
}
37+
}
38+
39+
struct CategoryItem: View {
40+
var landmark: Landmark
41+
var body: some View {
42+
VStack(alignment: .leading) {
43+
landmark.image
44+
.renderingMode(.original)
45+
.resizable()
46+
.frame(width: 155, height: 155)
47+
.cornerRadius(5)
48+
Text(landmark.name)
49+
.foregroundColor(.primary)
50+
.font(.caption)
51+
}
52+
.padding(.leading, 15)
53+
}
54+
}
55+
56+
struct CategoryRow_Previews: PreviewProvider {
57+
static var previews: some View {
58+
CategoryRow(
59+
categoryName: landmarkData[0].category.rawValue,
60+
items: Array(landmarkData.prefix(4))
61+
)
62+
.environmentObject(UserData())
63+
}
64+
}

0 commit comments

Comments
 (0)