Skip to content

Commit

Permalink
renamed to unsafeViewModifier, added example, added test for ShapeSource
Browse files Browse the repository at this point in the history
  • Loading branch information
hactar committed Jan 22, 2024
1 parent 77a5e07 commit f4c5ac3
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 7 deletions.
13 changes: 13 additions & 0 deletions Sources/MapLibreSwiftUI/Examples/Layers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,19 @@ struct Layer_Previews: PreviewProvider {
}
.ignoresSafeArea(.all)
.previewDisplayName("Rotated Symbols (Dynamic)")

MapView(styleURL: demoTilesURL) {
// Demonstrates how to use the unsafeMapModifier to set MLNMapView properties that have not been exposed as modifiers yet.
SymbolStyleLayer(identifier: "simple-symbols", source: pointSource)
.iconImage(constant: UIImage(systemName: "mappin")!)
}
.unsafeMapViewModifier({ mapView in
// Not all properties have modifiers yet. Until they do, you can use this 'escape hatch' to the underlying MLNMapView. Be careful: if you modify properties that the DSL controls already, they may be overridden. This modifier is a "hack", not a final function.
mapView.logoView.isHidden = false
mapView.compassViewPosition = .topLeft
})
.ignoresSafeArea(.all)
.previewDisplayName("Unsafe MapView Modifier")

// FIXME: This appears to be broken upstream; waiting for a new release
// MapView(styleURL: demoTilesURL) {
Expand Down
24 changes: 17 additions & 7 deletions Sources/MapLibreSwiftUI/MapView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ public struct MapView: UIViewRepresentable {

let styleSource: MapStyleSource
let userLayers: [StyleLayerDefinition]
var mapViewModifier: ((MLNMapView) -> Void)?

/// 'Escape hatch' to MLNMapView until we have more modifiers.
/// See ``unsafeMapViewModifier(_:)``
private var unsafeMapViewModifier: ((MLNMapView) -> Void)?

public init(
styleURL: URL,
Expand All @@ -30,10 +33,17 @@ public struct MapView: UIViewRepresentable {
self.init(styleURL: styleURL, camera: .constant(initialCamera), makeMapContent)
}

/// Allows you to set properties of the underlying MLNMapView directly.
/// Allows you to set properties of the underlying MLNMapView directly
/// in cases where these have not been ported to DSL yet.
/// Use this function to modify various properties of the MLNMapView instance.
/// For example, you can enable the display of the user's location on the map by setting `showUserLocation` to true.
///
/// This is an 'escape hatch' back to the non-DSL world
/// of MapLibre for features that have not been ported to DSL yet.
/// Be careful not to use this to modify properties that are
/// already ported to the DSL, like the camera for example, as your
/// modifications here may break updates that occur with modifiers.
///
/// - Parameter modifier: A closure that provides you with an MLNMapView so you can set properties.
/// - Returns: A MapView with the modifications applied.
///
Expand All @@ -45,9 +55,9 @@ public struct MapView: UIViewRepresentable {
/// }
/// ```
///
public func mapViewModifier(_ modifier: @escaping (MLNMapView) -> Void) -> MapView {
public func unsafeMapViewModifier(_ modifier: @escaping (MLNMapView) -> Void) -> MapView {
var newMapView = self
newMapView.mapViewModifier = modifier
newMapView.unsafeMapViewModifier = modifier
return newMapView
}

Expand Down Expand Up @@ -214,9 +224,9 @@ public struct MapView: UIViewRepresentable {

public func updateUIView(_ mapView: MLNMapView, context: Context) {
context.coordinator.parent = self
if let mapViewModifier {
mapViewModifier(mapView)
}

unsafeMapViewModifier?(mapView)

// FIXME: This should be a more selective update
context.coordinator.updateStyleSource(styleSource, mapView: mapView)
context.coordinator.updateLayers(mapView: mapView)
Expand Down
20 changes: 20 additions & 0 deletions Tests/MapLibreSwiftDSLTests/ShapeSourceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,24 @@ final class ShapeSourceTests: XCTestCase {
XCTFail("Expected a feature source")
}
}

func testForInAndCombinationFeatureBuilder() throws {
// ShapeSource now accepts 'for in' building, arrays, and combinations of them
let shapeSource = ShapeSource(identifier: "foo") {
for coordinates in samplePedestrianWaypoints {
MLNPointFeature(coordinate: coordinates)
}
MLNPointFeature(coordinate: CLLocationCoordinate2D(latitude: 48.2082, longitude: 16.3719))
}

XCTAssertEqual(shapeSource.identifier, "foo")

switch shapeSource.data {
case .features(let features):
XCTAssertEqual(features.count, 48)
default:
XCTFail("Expected a feature source")
}
}

}

0 comments on commit f4c5ac3

Please sign in to comment.