Skip to content

Commit 5290b28

Browse files
authored
MAPSIOS-1670: *-use-theme adoption (#2432)
1 parent 87dd9f6 commit 5290b28

File tree

57 files changed

+1181
-172
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+1181
-172
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Mapbox welcomes participation and contributions from everyone.
55
## main
66

77
* Add support for the `maxOverscaleFactorForParentTiles` property in `CustomRasterSource` and `CustomGeometrySource`, allowing greater control over tile overscaling behavior when rendering custom raster tiles.
8+
* Add support for experimental *-use-theme propert that allow to override the color theme set on the Map. This is experimental and have several limitations - currently expressions are not supported. Color properties in Lights, Rain, Snow are not supported. *-use-theme for layer applied only after zoom level change.
89

910
## 11.10.0-beta.1 - 20 January, 2025
1011

Examples.xcodeproj/project.pbxproj

Lines changed: 104 additions & 120 deletions
Large diffs are not rendered by default.
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import UIKit
2+
@_spi(Experimental) import MapboxMaps
3+
4+
final class ColorThemeMapExample: UIViewController, ExampleProtocol {
5+
private var mapView: MapView!
6+
private var mapUseTheme = true
7+
private var circleUseTheme = true
8+
private var cancellables = Set<AnyCancelable>()
9+
10+
override func viewDidLoad() {
11+
super.viewDidLoad()
12+
13+
let mapInitOptions = MapInitOptions(styleURI: .streets)
14+
mapView = MapView(frame: view.bounds, mapInitOptions: mapInitOptions)
15+
16+
view.addSubview(mapView)
17+
view.backgroundColor = .skyBlue
18+
mapView.translatesAutoresizingMaskIntoConstraints = false
19+
NSLayoutConstraint.activate([
20+
mapView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
21+
mapView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
22+
mapView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
23+
mapView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
24+
])
25+
26+
try! mapView.mapboxMap.setColorTheme(ColorTheme(uiimage: UIImage(named: "monochrome_lut")!))
27+
addTestLayer()
28+
29+
mapView.gestures.onMapTap.observe { _ in
30+
self.mapUseTheme.toggle()
31+
if self.mapUseTheme {
32+
try! self.mapView.mapboxMap.setColorTheme(ColorTheme(uiimage: UIImage(named: "monochrome_lut")!))
33+
} else {
34+
try! self.mapView.mapboxMap.removeColorTheme()
35+
}
36+
}
37+
.store(in: &cancellables)
38+
39+
mapView.gestures.onLayerTap("blue-layer") { _, _ in
40+
self.circleUseTheme.toggle()
41+
self.addTestLayer(useTheme: self.circleUseTheme)
42+
return true
43+
}
44+
.store(in: &cancellables)
45+
}
46+
47+
private func addTestLayer(
48+
id: String = "blue-layer",
49+
radius: LocationDistance = 2,
50+
color: UIColor = .blue,
51+
coordinate: CLLocationCoordinate2D = .init(latitude: 40, longitude: -104),
52+
useTheme: Bool = true
53+
) {
54+
let sourceId = "\(id)-source"
55+
try? mapView.mapboxMap.removeLayer(withId: id)
56+
try? mapView.mapboxMap.removeLayer(withId: "\(id)-border")
57+
try? mapView.mapboxMap.removeSource(withId: sourceId)
58+
59+
mapView.mapboxMap.setMapStyleContent {
60+
FillLayer(id: id, source: sourceId)
61+
.fillColorUseTheme(useTheme ? .default : .none)
62+
.fillColor(color)
63+
.fillOpacity(0.4)
64+
LineLayer(id: "\(id)-border", source: sourceId)
65+
.lineColor(color.darker)
66+
.lineColorUseTheme(useTheme ? .default : .none)
67+
.lineOpacity(0.4)
68+
.lineWidth(2)
69+
GeoJSONSource(id: sourceId)
70+
.data(.geometry(.polygon(Polygon(center: coordinate, radius: radius * 1000000, vertices: 60))))
71+
}
72+
}
73+
74+
override func viewDidAppear(_ animated: Bool) {
75+
super.viewDidAppear(animated)
76+
// The below line is used for internal testing purposes only.
77+
finish()
78+
}
79+
}

Sources/Examples/Models/Examples.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,9 @@ struct Examples {
141141
Example(title: "Combine",
142142
description: "Shows how to use map events with Combine framework.",
143143
type: CombineExample.self)
144+
Example(title: "Color Theme Example",
145+
description: "Shows how to use color theme",
146+
type: ColorThemeMapExample.self)
144147
Example(title: "Combine location",
145148
description: "Shows how to use Combine framework to drive the location puck.",
146149
type: CombineLocationExample.self)

Sources/Examples/SwiftUI Examples/ColorThemeExample.swift

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@ struct ColorThemeExample: View {
1010

1111
@State private var theme: Theme = .red
1212
@State private var panelHeight: CGFloat = 0
13+
@State private var atmosphereUseTheme = true
14+
@State private var circleUseTheme = true
1315

1416
var body: some View {
15-
Map(initialViewport: .camera(center: .init(latitude: 40.72, longitude: -73.99), zoom: 11, pitch: 45)) {
17+
Map(initialViewport: .camera(center: .init(latitude: 40.72, longitude: -73.99), zoom: 2, pitch: 45)) {
1618
switch theme {
1719
case .default:
1820
EmptyMapContent()
@@ -22,8 +24,12 @@ struct ColorThemeExample: View {
2224
ColorTheme(uiimage: monochromeTheme)
2325
}
2426

25-
/// Defines a custom layer and source to draw the border line.
26-
NYNJBorder()
27+
Atmosphere()
28+
.color(.green)
29+
.colorUseTheme(atmosphereUseTheme ? .default : .none)
30+
31+
TestLayer(id: "blue-layer", radius: 2, color: .blue, coordinate: .init(latitude: 40, longitude: -104), useTheme: circleUseTheme)
32+
2733
}
2834
.mapStyle(.streets) /// In standard style it's possible to provide custom theme using `.standard(themeData: "base64String")`
2935
.additionalSafeAreaInsets(.bottom, panelHeight)
@@ -36,6 +42,9 @@ struct ColorThemeExample: View {
3642
ColorButton(color: .red, isOn: Binding(get: { theme == .red }, set: { _, _ in theme = .red }))
3743
ColorButton(color: .secondaryLabel, isOn: Binding(get: { theme == .monochrome }, set: { _, _ in theme = .monochrome }))
3844
}
45+
46+
Toggle("Atmosphere Use Theme", isOn: $atmosphereUseTheme)
47+
Toggle("Circle Use Theme", isOn: $circleUseTheme)
3948
}
4049
.floating()
4150
}
@@ -82,33 +91,33 @@ private struct ColorButton: View {
8291
}
8392
}
8493

85-
private struct NYNJBorder: MapContent {
86-
var body: some MapContent {
87-
GeoJSONSource(id: "border")
88-
.data(.geometry(.lineString(LineString([
89-
CLLocationCoordinate2D(latitude: 40.913503418907936, longitude: -73.91912400100642),
90-
CLLocationCoordinate2D(latitude: 40.82943110786286, longitude: -73.9615887363045),
91-
CLLocationCoordinate2D(latitude: 40.75461056309348, longitude: -74.01409059085539),
92-
CLLocationCoordinate2D(latitude: 40.69522028220487, longitude: -74.02798814058939),
93-
CLLocationCoordinate2D(latitude: 40.65188756398558, longitude: -74.05655532615407),
94-
CLLocationCoordinate2D(latitude: 40.64339339389301, longitude: -74.13916853846217),
95-
]))))
94+
private struct TestLayer: MapStyleContent {
95+
var id: String
96+
var radius: LocationDistance
97+
var color: UIColor
98+
var coordinate: CLLocationCoordinate2D
99+
var useTheme: Bool
96100

97-
LineLayer(id: "border", source: "border")
98-
.lineColor(.orange)
99-
.lineWidth(8)
100-
.slot(.bottom)
101+
var body: some MapStyleContent {
102+
let sourceId = "\(id)-source"
103+
FillLayer(id: id, source: sourceId)
104+
.fillColorUseTheme(useTheme ? .default : .none)
105+
.fillColor(color)
106+
.fillOpacity(0.4)
107+
LineLayer(id: "\(id)-border", source: sourceId)
108+
.lineColor(color.darker)
109+
.lineColorUseTheme(useTheme ? .default : .none)
110+
.lineOpacity(0.4)
111+
.lineWidth(2)
112+
GeoJSONSource(id: sourceId)
113+
.data(.geometry(.polygon(Polygon(center: coordinate, radius: radius * 1000000, vertices: 60))))
101114
}
102115
}
103116

104117
private let styleURL = Bundle.main.url(forResource: "fragment-realestate-NY", withExtension: "json")!
105118
private let monochromeTheme = UIImage(named: "monochrome_lut")!
106119
private let redTheme = "iVBORw0KGgoAAAANSUhEUgAABAAAAAAgCAYAAACM/gqmAAAAAXNSR0IArs4c6QAABSFJREFUeF7t3cFO40AQAFHnBv//wSAEEgmJPeUDsid5h9VqtcMiZsfdPdXVzmVZlo+3ZVm+fr3//L7257Lm778x+prL1ff0/b//H+z/4/M4OkuP/n70Nc7f+nnb+yzb//sY6vxt5xXPn+dP/aH+GsXJekb25izxR/ypZ6ucUefv9g4z2jPP3/HPHwAAgABAABgACIACkAAsAL1SD4yKWQAUAHUBdAG8buKNYoYL8PEX4FcHQAAAAAAAAAAAAAAAAAAAAAAA8LAeGF1mABAABAABQACQbZP7+hk5AwACAAAAAAAAAAAAAAAAAAAAAAAA4EE9AICMx4QBAAAAAAAANgvJsxGQV1dA/PxmMEtxU9YoABQACoC5CgDxX/wvsb2sEf/Ff/Ff/N96l5n73+/5YAB4CeBqx2VvMqXgUfD2npkzBCAXEBeQcrkoa5x/FxAXEBcQF5A2Wy3/t32qNYr8I//Mln+MABgBMAJgBMAIgBEAIwBGAIwAGAEwAmAE4K4eAGCNQIw+qQ0AmQ+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/6gEABAB5RgACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN/UAAPKcAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgEFNODICRtDkDO/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOhvlPUWem+h9xKQ+V4CUt9wO6KZnn/Pv+ff8z/bW5DFP59CUnJbWSP+iX/iX78znqED/urxnwHAAGAAMAAYAAwABgADgAHAAGAAMAAYAAwABgADoNMcHUAdQAQcAUfAe8xEwH0O86t3IPz8OvClu17WqD/UH+oP9cf1Gdia01d/LQsDgAHAAGAAMAAYAAwABgADgAHAAGAAMAAYAAwABkCnSQwABgACj8Aj8D1mItAMAB1wHfDS3S5r5F/5V/6Vf3XAW12h/mIArHY89iZTAAQA2XtmBKAWqOslyf4rgBXACmAFcIur8k/bJ/mnQTr5V/6Vf+fKv0YAjAAYATACYATACIARACMARgCMABgBMAJgBMAIgBEAIwCdZuiA64AjwAgwAtxjpg6cDlztLlLA7/Pr1gueyr56/jx/5ZzUNeof9Y/6R/0zk4HGAGAAMAAYAAwABgADgAHAAGAAMAAYAAwABgADgAHQaQ4DgAGAgCPgCHiPmTqQOpC1u8gAYACMjAf5V/6Vf+XfmTrQ8l97v8Z/5X8GAAOAAcAAYAAwABgADAAGAAOAAcAAYAAwABgADIBO0xgADAAdCB0IHYgeMxkADAAdkGM7IPbf/pfuWlmj/lH/qH/UPzMZGAwABgADgAHAAGAAMAAYAAwABgADgAHAAGAAMAAYAJ3mMAAYAAg4Ao6A95jJAGAA6EDrQJfuclkj/8q/8q/8O1MHWv47Nv8xABgADAAGAAOAAcAAYAAwABgADAAGAAOAAcAAYAB0msYAYADoQOhA6ED0mMkAYADogBzbAbH/9r/YFWWN+kf9o/5R/8xkYDAAGAAMAAYAA4ABwABgADAAGAAMAAYAA4ABwABgAHSawwBgACDgCDgC3mMmA4ABoAOtA126y2WN/Cv/yr/y70wdaPnv2PzHAGAAMAAYAAwABgADgAHAAGAAMAAYAAwABgADgAHQaRoDgAGgA6EDoQPRYyYDgAGgA3JsB8T+2/9iV5Q16h/1j/pH/TOTgcEAYAAwABgADAAGAAOAAcAAYAAwABgADAAGAAPgyQ2AT4NBIB3ew5dkAAAAAElFTkSuQmCC"
107120

108-
private extension StandardTheme {
109-
static let red = StandardTheme(rawValue: "red")
110-
}
111-
112121
struct ColorThemeExample_Previews: PreviewProvider {
113122
static var previews: some View {
114123
StandardStyleImportExample()

Sources/MapboxMaps/Documentation.docc/API Catalogs/Style.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
- ``Rain``
3030
- ``Snow``
3131
- ``ColorTheme``
32+
- ``ColorUseTheme``
3233

3334
### Declarative Map Styling
3435

Sources/MapboxMaps/Style/Generated/Atmosphere.swift

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

0 commit comments

Comments
 (0)