Skip to content

Commit f309cc0

Browse files
authored
Merge pull request #9 from mapbox/pjl/add-ios-interactions
Add Interactions API for iOS Tutorial
2 parents 38594d1 + 1c09b3d commit f309cc0

File tree

14 files changed

+1147
-0
lines changed

14 files changed

+1147
-0
lines changed

ios-interactions/Interactions.xcodeproj/project.pbxproj

Lines changed: 614 additions & 0 deletions
Large diffs are not rendered by default.

ios-interactions/Interactions.xcodeproj/project.xcworkspace/contents.xcworkspacedata

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ios-interactions/Interactions.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

Lines changed: 42 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"colors" : [
3+
{
4+
"idiom" : "universal"
5+
}
6+
],
7+
"info" : {
8+
"author" : "xcode",
9+
"version" : 1
10+
}
11+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"images" : [
3+
{
4+
"idiom" : "universal",
5+
"platform" : "ios",
6+
"size" : "1024x1024"
7+
},
8+
{
9+
"appearances" : [
10+
{
11+
"appearance" : "luminosity",
12+
"value" : "dark"
13+
}
14+
],
15+
"idiom" : "universal",
16+
"platform" : "ios",
17+
"size" : "1024x1024"
18+
},
19+
{
20+
"appearances" : [
21+
{
22+
"appearance" : "luminosity",
23+
"value" : "tinted"
24+
}
25+
],
26+
"idiom" : "universal",
27+
"platform" : "ios",
28+
"size" : "1024x1024"
29+
}
30+
],
31+
"info" : {
32+
"author" : "xcode",
33+
"version" : 1
34+
}
35+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"info" : {
3+
"author" : "xcode",
4+
"version" : 1
5+
}
6+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import SwiftUI
2+
import MapboxMaps
3+
4+
struct ContentView: View {
5+
@State var selectedPlaces = [StandardPlaceLabelsFeature]()
6+
@State private var selectedPriceLabel: FeaturesetFeature?
7+
8+
var body: some View {
9+
Map(initialViewport: .camera(center: .init(latitude: 40.72, longitude: -73.99), zoom: 11, pitch: 45)) {
10+
StyleImport(id: "new-york-hotels", uri: StyleURI(url: styleURL)!)
11+
12+
TapInteraction(.standardPlaceLabels) { placeLabel, _ in
13+
selectedPlaces.append(placeLabel)
14+
return true
15+
}
16+
17+
ForEvery(selectedPlaces, id: \.id) { placeLabel in
18+
FeatureState(placeLabel, .init(select: true))
19+
}
20+
21+
LongPressInteraction { _ in
22+
selectedPlaces.removeAll()
23+
return true
24+
}
25+
26+
TapInteraction(.featureset("hotels-price", importId: "new-york-hotels")) { priceLabel, _ in
27+
/// Select a price label when it's clicked
28+
selectedPriceLabel = priceLabel
29+
return true
30+
}
31+
32+
if let selectedPriceLabel, let coordinate = selectedPriceLabel.geometry.point?.coordinates {
33+
/// When there's a selected price label, we use it to set a feature state.
34+
/// The `hidden` state is implemented in `new-york-hotels.json` and hides label and icon.
35+
FeatureState(selectedPriceLabel, ["hidden": true])
36+
37+
/// Instead of label we show a callout annotation with animation.
38+
MapViewAnnotation(coordinate: coordinate) {
39+
HotelCallout(feature: selectedPriceLabel)
40+
/// The `id` makes the view to be re-created for each unique feature
41+
/// so appearing animation plays each time.
42+
.id(selectedPriceLabel.id)
43+
}
44+
.variableAnchors([.init(anchor: .bottom)])
45+
}
46+
}
47+
.mapStyle(.standard(
48+
lightPreset: .dawn
49+
))
50+
.ignoresSafeArea()
51+
}
52+
}
53+
54+
private struct HotelCallout: View {
55+
var feature: FeaturesetFeature
56+
57+
@State private var scale: CGFloat = 0.1
58+
59+
var body: some View {
60+
VStack(alignment: .center, spacing: 2) {
61+
Text(feature.properties["name"]??.string ?? "")
62+
.font(.headline)
63+
.foregroundColor(.black)
64+
Text(feature.properties["price"]??.number.map { "$ \(Int($0))" } ?? "")
65+
.font(.subheadline)
66+
.foregroundColor(.green)
67+
.fontWeight(.bold)
68+
}
69+
.padding(6)
70+
.background(Color.white.opacity(0.9))
71+
.cornerRadius(8)
72+
.scaleEffect(scale, anchor: .bottom)
73+
.onAppear {
74+
withAnimation(Animation.interpolatingSpring(stiffness: 200, damping: 16)) {
75+
scale = 1.0
76+
}
77+
}
78+
}
79+
}
80+
81+
private let styleURL = Bundle.main.url(forResource: "new-york-hotels", withExtension: "json")!
82+
83+
#Preview {
84+
ContentView()
85+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>MBXAccessToken</key>
6+
<string>YOUR_MAPBOX_ACCESS_TOKEN</string>
7+
</dict>
8+
</plist>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import SwiftUI
2+
3+
@main
4+
struct InteractionsApp: App {
5+
var body: some Scene {
6+
WindowGroup {
7+
ContentView()
8+
}
9+
}
10+
}

0 commit comments

Comments
 (0)