Skip to content

Commit

Permalink
[CP] MAPSIOS-1670: *-use-theme adoption (#2436)
Browse files Browse the repository at this point in the history
  • Loading branch information
aleksproger authored Jan 31, 2025
1 parent f9b6b36 commit afed663
Show file tree
Hide file tree
Showing 57 changed files with 1,085 additions and 52 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

Mapbox welcomes participation and contributions from everyone.

## main

* Add support for the `maxOverscaleFactorForParentTiles` property in `CustomRasterSource` and `CustomGeometrySource`, allowing greater control over tile overscaling behavior when rendering custom raster tiles.
* 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.

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

* Mark `SymbolElevationReference`, `FillExtrusionBaseAlignment`, `FillExtrusionHeightAlignment`, `ModelScaleMode`, `ModelType`, `ClipLayerTypes`, `BackgroundPitchAlignment` types as Experimental. Initially they were exposed as stable by mistake. If you use them, please import `MapboxMaps` with `Experimental` SPI:
Expand Down
4 changes: 4 additions & 0 deletions Examples.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
634BA74F4E553C53EE906F5A /* OfflineManagerExample.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 000D0E4CEFB6D5AF02518807 /* OfflineManagerExample.storyboard */; platformFilters = (ios, ); };
64F4FA139388DB34564AD42D /* CLLocationCoordinate2D+Random.swift in Sources */ = {isa = PBXBuildFile; fileRef = 455C0B9F01316D0FF38ED62B /* CLLocationCoordinate2D+Random.swift */; platformFilters = (ios, ); };
655105BD0FAFF4C4BA65DC32 /* ExamplesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EE19F00E87B31FDE5481D56 /* ExamplesTests.swift */; platformFilters = (ios, ); };
65E9F2B993AEB394FC2D0080 /* ColorThemeMapExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50F519EC4AF0B4BEE0FDCABC /* ColorThemeMapExample.swift */; platformFilters = (ios, ); };
6661DB69D4980E24BCA18AB2 /* PolygonAnnotationExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DCBE4524A8793B4DE950533 /* PolygonAnnotationExample.swift */; platformFilters = (ios, ); };
68FD9E1F4606B2729BA1E6DC /* SnapshotterExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 588FD640D91E9DD366703F7B /* SnapshotterExample.swift */; platformFilters = (ios, ); };
6B040F65241ABF600D70D14D /* Custom3DPuckExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C957F9CA07061B793C2DD4A /* Custom3DPuckExample.swift */; platformFilters = (ios, ); };
Expand Down Expand Up @@ -225,6 +226,7 @@
4DCBE814694CF08A9C2E4A42 /* AddOneMarkerSymbolExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddOneMarkerSymbolExample.swift; sourceTree = "<group>"; };
4EE19F00E87B31FDE5481D56 /* ExamplesTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExamplesTests.swift; sourceTree = "<group>"; };
50618B3CF42CCF735CCAE9B4 /* fragment-realestate-NY.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "fragment-realestate-NY.json"; sourceTree = "<group>"; };
50F519EC4AF0B4BEE0FDCABC /* ColorThemeMapExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorThemeMapExample.swift; sourceTree = "<group>"; };
524D79FF01638A0E8A3C1248 /* .swiftlint.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = .swiftlint.yml; sourceTree = "<group>"; };
588FD640D91E9DD366703F7B /* SnapshotterExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SnapshotterExample.swift; sourceTree = "<group>"; };
590D83805AA598D2B0A7638A /* ExamplesTests.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = ExamplesTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -632,6 +634,7 @@
F4E57BB1463BD6558C9EE37A /* Lab */ = {
isa = PBXGroup;
children = (
50F519EC4AF0B4BEE0FDCABC /* ColorThemeMapExample.swift */,
8DBF737C9C7FBF46BB5F7B78 /* CombineExample.swift */,
A4EE8F38428A64B5B9D4DBBE /* CombineLocationExample.swift */,
60A8CD8A69D3429FCF8ACBDD /* Lights3DExample.swift */,
Expand Down Expand Up @@ -859,6 +862,7 @@
1DAE02D73D16E543777C2025 /* ClusteringExample.swift in Sources */,
5A28C124249725578389175A /* ColorExpressionExample.swift in Sources */,
DA109856E64BBD8071DF0619 /* ColorThemeExample.swift in Sources */,
65E9F2B993AEB394FC2D0080 /* ColorThemeMapExample.swift in Sources */,
C664365A373267B564EC84EE /* CombineExample.swift in Sources */,
215230836B6AD1040D3DA547 /* CombineLocationExample.swift in Sources */,
3E515D1DD1D9CA02F3E95AA2 /* Constants.swift in Sources */,
Expand Down
79 changes: 79 additions & 0 deletions Sources/Examples/All Examples/Lab/ColorThemeMapExample.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import UIKit
@_spi(Experimental) import MapboxMaps

final class ColorThemeMapExample: UIViewController, ExampleProtocol {
private var mapView: MapView!
private var mapUseTheme = true
private var circleUseTheme = true
private var cancellables = Set<AnyCancelable>()

override func viewDidLoad() {
super.viewDidLoad()

let mapInitOptions = MapInitOptions(styleURI: .streets)
mapView = MapView(frame: view.bounds, mapInitOptions: mapInitOptions)

view.addSubview(mapView)
view.backgroundColor = .skyBlue
mapView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
mapView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
mapView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
mapView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
mapView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
])

try! mapView.mapboxMap.setColorTheme(ColorTheme(uiimage: UIImage(named: "monochrome_lut")!))
addTestLayer()

mapView.gestures.onMapTap.observe { _ in
self.mapUseTheme.toggle()
if self.mapUseTheme {
try! self.mapView.mapboxMap.setColorTheme(ColorTheme(uiimage: UIImage(named: "monochrome_lut")!))
} else {
try! self.mapView.mapboxMap.removeColorTheme()
}
}
.store(in: &cancellables)

mapView.gestures.onLayerTap("blue-layer") { _, _ in
self.circleUseTheme.toggle()
self.addTestLayer(useTheme: self.circleUseTheme)
return true
}
.store(in: &cancellables)
}

private func addTestLayer(
id: String = "blue-layer",
radius: LocationDistance = 2,
color: UIColor = .blue,
coordinate: CLLocationCoordinate2D = .init(latitude: 40, longitude: -104),
useTheme: Bool = true
) {
let sourceId = "\(id)-source"
try? mapView.mapboxMap.removeLayer(withId: id)
try? mapView.mapboxMap.removeLayer(withId: "\(id)-border")
try? mapView.mapboxMap.removeSource(withId: sourceId)

mapView.mapboxMap.setMapStyleContent {
FillLayer(id: id, source: sourceId)
.fillColorUseTheme(useTheme ? .default : .none)
.fillColor(color)
.fillOpacity(0.4)
LineLayer(id: "\(id)-border", source: sourceId)
.lineColor(color.darker)
.lineColorUseTheme(useTheme ? .default : .none)
.lineOpacity(0.4)
.lineWidth(2)
GeoJSONSource(id: sourceId)
.data(.geometry(.polygon(Polygon(center: coordinate, radius: radius * 1000000, vertices: 60))))
}
}

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// The below line is used for internal testing purposes only.
finish()
}
}
3 changes: 3 additions & 0 deletions Sources/Examples/Models/Examples.swift
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@ struct Examples {
Example(title: "Combine",
description: "Shows how to use map events with Combine framework.",
type: CombineExample.self)
Example(title: "Color Theme Example",
description: "Shows how to use color theme",
type: ColorThemeMapExample.self)
Example(title: "Combine location",
description: "Shows how to use Combine framework to drive the location puck.",
type: CombineLocationExample.self)
Expand Down
53 changes: 31 additions & 22 deletions Sources/Examples/SwiftUI Examples/ColorThemeExample.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ struct ColorThemeExample: View {

@State private var theme: Theme = .red
@State private var panelHeight: CGFloat = 0
@State private var atmosphereUseTheme = true
@State private var circleUseTheme = true

var body: some View {
Map(initialViewport: .camera(center: .init(latitude: 40.72, longitude: -73.99), zoom: 11, pitch: 45)) {
Map(initialViewport: .camera(center: .init(latitude: 40.72, longitude: -73.99), zoom: 2, pitch: 45)) {
switch theme {
case .default:
EmptyMapContent()
Expand All @@ -22,8 +24,12 @@ struct ColorThemeExample: View {
ColorTheme(uiimage: monochromeTheme)
}

/// Defines a custom layer and source to draw the border line.
NYNJBorder()
Atmosphere()
.color(.green)
.colorUseTheme(atmosphereUseTheme ? .default : .none)

TestLayer(id: "blue-layer", radius: 2, color: .blue, coordinate: .init(latitude: 40, longitude: -104), useTheme: circleUseTheme)

}
.mapStyle(.streets) /// In standard style it's possible to provide custom theme using `.standard(themeData: "base64String")`
.additionalSafeAreaInsets(.bottom, panelHeight)
Expand All @@ -36,6 +42,9 @@ struct ColorThemeExample: View {
ColorButton(color: .red, isOn: Binding(get: { theme == .red }, set: { _, _ in theme = .red }))
ColorButton(color: .secondaryLabel, isOn: Binding(get: { theme == .monochrome }, set: { _, _ in theme = .monochrome }))
}

Toggle("Atmosphere Use Theme", isOn: $atmosphereUseTheme)
Toggle("Circle Use Theme", isOn: $circleUseTheme)
}
.floating()
}
Expand Down Expand Up @@ -82,33 +91,33 @@ private struct ColorButton: View {
}
}

private struct NYNJBorder: MapContent {
var body: some MapContent {
GeoJSONSource(id: "border")
.data(.geometry(.lineString(LineString([
CLLocationCoordinate2D(latitude: 40.913503418907936, longitude: -73.91912400100642),
CLLocationCoordinate2D(latitude: 40.82943110786286, longitude: -73.9615887363045),
CLLocationCoordinate2D(latitude: 40.75461056309348, longitude: -74.01409059085539),
CLLocationCoordinate2D(latitude: 40.69522028220487, longitude: -74.02798814058939),
CLLocationCoordinate2D(latitude: 40.65188756398558, longitude: -74.05655532615407),
CLLocationCoordinate2D(latitude: 40.64339339389301, longitude: -74.13916853846217),
]))))
private struct TestLayer: MapStyleContent {
var id: String
var radius: LocationDistance
var color: UIColor
var coordinate: CLLocationCoordinate2D
var useTheme: Bool

LineLayer(id: "border", source: "border")
.lineColor(.orange)
.lineWidth(8)
.slot(.bottom)
var body: some MapStyleContent {
let sourceId = "\(id)-source"
FillLayer(id: id, source: sourceId)
.fillColorUseTheme(useTheme ? .default : .none)
.fillColor(color)
.fillOpacity(0.4)
LineLayer(id: "\(id)-border", source: sourceId)
.lineColor(color.darker)
.lineColorUseTheme(useTheme ? .default : .none)
.lineOpacity(0.4)
.lineWidth(2)
GeoJSONSource(id: sourceId)
.data(.geometry(.polygon(Polygon(center: coordinate, radius: radius * 1000000, vertices: 60))))
}
}

private let styleURL = Bundle.main.url(forResource: "fragment-realestate-NY", withExtension: "json")!
private let monochromeTheme = UIImage(named: "monochrome_lut")!
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"

private extension StandardTheme {
static let red = StandardTheme(rawValue: "red")
}

struct ColorThemeExample_Previews: PreviewProvider {
static var previews: some View {
StandardStyleImportExample()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
- ``Rain``
- ``Snow``
- ``ColorTheme``
- ``ColorUseTheme``

### Declarative Map Styling

Expand Down
Loading

0 comments on commit afed663

Please sign in to comment.