From 2e9007df58f26ad74f5b258a64bd301698b52029 Mon Sep 17 00:00:00 2001 From: Roman Laitarenko Date: Mon, 20 Jan 2025 11:09:36 +0200 Subject: [PATCH] Add `ViewAnnotationOptions.priority` (#2398) --- CHANGELOG.md | 4 + .../xcshareddata/swiftpm/Package.resolved | 8 +- LICENSE.md | 4 +- MapboxMaps.podspec | 4 +- Package.resolved | 8 +- Package.swift | 4 +- .../DynamicViewAnnotationExample.swift | 16 ++- .../ViewAnnotationBasicExample.swift | 2 +- .../ViewAnnotationMarkerExample.swift | 12 +- ...AnnotationWithPointAnnotationExample.swift | 3 +- .../ViewAnnotationsExample.swift | 7 +- .../Annotations/ViewAnnotation.swift | 31 +++++ .../Annotations/ViewAnnotationOptions.swift | 110 +++++++++++++++++- .../MapContent/MountedViewAnnotation.swift | 3 + .../Annotations/MapViewAnnotation.swift | 31 +++++ .../ViewAnnotationOptionsTests.swift | 22 ++-- .../Annotations/ViewAnntoationTests.swift | 14 +-- .../Style/StyleIntegrationTests.swift | 4 +- .../breakage_allowlist.txt | 3 + scripts/release/packager/versions.json | 4 +- scripts/release/sync_deps_versions.sh | 2 +- 21 files changed, 247 insertions(+), 49 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a675efd26d7..b9767923f9bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,10 @@ CircleAnnotationGroup {} // new .slot(.middle) ``` +* Introduce `ViewAnnotation.priority`, deprecate `ViewAnnotation.selected`. +Use this property to define view annotation sort order. +* Introduce `ViewAnnotation.minZoom` and `ViewAnnotation.maxZoom`. Use these properties to configure zoom-level specific view annotations. +* Update CoreMaps to 11.10.0-beta.2 and Common to 24.10.0-beta.2. ## 11.9.0 - 18 December, 2024 diff --git a/Examples.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Examples.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 407265999957..23e69d7ad365 100644 --- a/Examples.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Examples.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -14,8 +14,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/mapbox/mapbox-common-ios.git", "state" : { - "revision" : "480f648b20b87a3a55f30bb6d76d6dc7d8412ec4", - "version" : "24.9.0" + "revision" : "94a111e4e8b0f7f8d5f79cc84c832757fadd280d", + "version" : "24.10.0-beta.2" } }, { @@ -23,8 +23,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/mapbox/mapbox-core-maps-ios.git", "state" : { - "revision" : "9fdb574d24d4a012a051d6a875e1c2753796de07", - "version" : "11.9.0" + "revision" : "2324ba61b603fd73f9b4b913437c910bb33bc405", + "version" : "11.10.0-beta.2" } }, { diff --git a/LICENSE.md b/LICENSE.md index 20d33a63bab3..244970b1846f 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -31,13 +31,13 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. --- -### MapboxCoreMaps,11.9.0,Mapbox ToS,Mapbox,https://www.mapbox.com/ +### MapboxCoreMaps,11.10.0-beta.2,Mapbox ToS,Mapbox,https://www.mapbox.com/ ``` Mapbox Core Maps version 11.0 Mapbox Core Maps SDK -Copyright (c) 2024 Mapbox +Copyright (c) 2025 Mapbox All rights reserved. diff --git a/MapboxMaps.podspec b/MapboxMaps.podspec index d349b8003688..7426f21e7a2d 100644 --- a/MapboxMaps.podspec +++ b/MapboxMaps.podspec @@ -21,8 +21,8 @@ Pod::Spec.new do |m| m.source_files = 'Sources/MapboxMaps/**/*.{swift,h}' m.resource_bundles = { 'MapboxMapsResources' => ['Sources/**/*.{xcassets,strings}', 'Sources/MapboxMaps/MapboxMaps.json', 'Sources/MapboxMaps/PrivacyInfo.xcprivacy'] } - m.dependency 'MapboxCoreMaps', '11.9.0' - m.dependency 'MapboxCommon', '24.9.0' + m.dependency 'MapboxCoreMaps', '11.10.0-beta.2' + m.dependency 'MapboxCommon', '24.10.0-beta.2' m.dependency 'Turf', '4.0.0' end diff --git a/Package.resolved b/Package.resolved index 784cdfbd8ed2..6dc138cd3dd4 100644 --- a/Package.resolved +++ b/Package.resolved @@ -5,8 +5,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/mapbox/mapbox-common-ios.git", "state" : { - "revision" : "480f648b20b87a3a55f30bb6d76d6dc7d8412ec4", - "version" : "24.9.0" + "revision" : "94a111e4e8b0f7f8d5f79cc84c832757fadd280d", + "version" : "24.10.0-beta.2" } }, { @@ -14,8 +14,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/mapbox/mapbox-core-maps-ios.git", "state" : { - "revision" : "9fdb574d24d4a012a051d6a875e1c2753796de07", - "version" : "11.9.0" + "revision" : "2324ba61b603fd73f9b4b913437c910bb33bc405", + "version" : "11.10.0-beta.2" } }, { diff --git a/Package.swift b/Package.swift index 2ebb20798825..b08968503d4c 100644 --- a/Package.swift +++ b/Package.swift @@ -4,9 +4,9 @@ import PackageDescription import Foundation -let coreMaps = MapsDependency.coreMaps(version: "11.9.0") +let coreMaps = MapsDependency.coreMaps(version: "11.10.0-beta.2") -let common = MapsDependency.common(version: "24.9.0") +let common = MapsDependency.common(version: "24.10.0-beta.2") let mapboxMapsPath: String? = nil diff --git a/Sources/Examples/All Examples/Annotations/DynamicViewAnnotationExample.swift b/Sources/Examples/All Examples/Annotations/DynamicViewAnnotationExample.swift index 4810d2e767d0..8ee617f5fe4f 100644 --- a/Sources/Examples/All Examples/Annotations/DynamicViewAnnotationExample.swift +++ b/Sources/Examples/All Examples/Annotations/DynamicViewAnnotationExample.swift @@ -79,10 +79,12 @@ final class DynamicViewAnnotationExample: UIViewController, ExampleProtocol { addParkingAnnotation( coordinate: CLLocationCoordinate2D(latitude: 37.445, longitude: -122.1704), - text: "$6.99/hr") + text: "$6.99/hr", + minZoom: 12) addParkingAnnotation( coordinate: CLLocationCoordinate2D(latitude: 37.4441, longitude: -122.1691), - text: "$5.99/hr") + text: "$5.99/hr", + minZoom: 10) } private func loadRoutes() { @@ -161,16 +163,17 @@ final class DynamicViewAnnotationExample: UIViewController, ExampleProtocol { } } - private func addParkingAnnotation(coordinate: CLLocationCoordinate2D, text: String) { + private func addParkingAnnotation(coordinate: CLLocationCoordinate2D, text: String, minZoom: Double) { let view = ParkingAnnotationView(text: text) let annotation = ViewAnnotation(coordinate: coordinate, view: view) annotation.allowOverlap = true + annotation.minZoom = minZoom mapView.viewAnnotations.add(annotation) view.onTap = { [unowned view, unowned annotation] in - annotation.selected.toggle() - view.selected = annotation.selected + view.selected.toggle() + annotation.priority = view.selected ? 1 : 0 annotation.setNeedsUpdateSize() } } @@ -261,6 +264,7 @@ private final class Route { etaView.anchor = config.anchor } etaAnnotation.variableAnchors = .all + etaAnnotation.minZoom = 8 etaView.onTap = { [weak self] in self?.onTap?() } self.etaAnnotation = etaAnnotation @@ -290,7 +294,7 @@ private final class Route { } private func updateSelected() { - etaAnnotation?.selected = selected + etaAnnotation?.priority = selected ? 1 : 0 etaView?.selected = selected mapView?.mapboxMap.setFeatureState(sourceId: layerId, featureId: name, state: ["selected": selected]) {_ in} diff --git a/Sources/Examples/All Examples/Annotations/ViewAnnotationBasicExample.swift b/Sources/Examples/All Examples/Annotations/ViewAnnotationBasicExample.swift index 720c998d8f50..0cda10a3b6e1 100644 --- a/Sources/Examples/All Examples/Annotations/ViewAnnotationBasicExample.swift +++ b/Sources/Examples/All Examples/Annotations/ViewAnnotationBasicExample.swift @@ -35,7 +35,7 @@ final class ViewAnnotationBasicExample: UIViewController, ExampleProtocol { annotation.allowOverlap = true annotationView.onClose = { [weak annotation] in annotation?.remove() } annotationView.onSelect = { [weak annotation] selected in - annotation?.selected = selected + annotation?.priority = selected ? 1 : 0 annotation?.setNeedsUpdateSize() } mapView.viewAnnotations.add(annotation) diff --git a/Sources/Examples/All Examples/Annotations/ViewAnnotationMarkerExample.swift b/Sources/Examples/All Examples/Annotations/ViewAnnotationMarkerExample.swift index 07604867b3b8..1997e0f37171 100644 --- a/Sources/Examples/All Examples/Annotations/ViewAnnotationMarkerExample.swift +++ b/Sources/Examples/All Examples/Annotations/ViewAnnotationMarkerExample.swift @@ -7,6 +7,11 @@ final class ViewAnnotationMarkerExample: UIViewController, ExampleProtocol { private var pointList: [Feature] = [] private var markerId = 0 private var annotations = [String: ViewAnnotation]() + private var _topPriority = 0 + private var topPriority: Int { + _topPriority += 1 + return _topPriority + } private let image = UIImage(named: "intermediate-pin")! private lazy var markerHeight: CGFloat = image.size.height @@ -68,7 +73,7 @@ final class ViewAnnotationMarkerExample: UIViewController, ExampleProtocol { guard case let .string(id) = feature.identifier else { return false } if let annotation = annotations[id] { - annotation.visible.toggle() + annotation.priority = topPriority return true } return addViewAnnotation(to: feature) @@ -141,8 +146,9 @@ final class ViewAnnotationMarkerExample: UIViewController, ExampleProtocol { annotation?.remove() self?.annotations.removeValue(forKey: id) } - annotationView.onSelect = { [weak annotation] selected in - annotation?.selected = selected + annotationView.onSelect = { [weak annotation, weak self] _ in + guard let self else { return } + annotation?.priority = self.topPriority annotation?.setNeedsUpdateSize() } diff --git a/Sources/Examples/All Examples/Annotations/ViewAnnotationWithPointAnnotationExample.swift b/Sources/Examples/All Examples/Annotations/ViewAnnotationWithPointAnnotationExample.swift index d89127042d75..e1f29cc5a230 100644 --- a/Sources/Examples/All Examples/Annotations/ViewAnnotationWithPointAnnotationExample.swift +++ b/Sources/Examples/All Examples/Annotations/ViewAnnotationWithPointAnnotationExample.swift @@ -70,8 +70,7 @@ final class ViewAnnotationWithPointAnnotationExample: UIViewController, ExampleP annotation?.remove() self?.annotation = nil } - annotationView.onSelect = { [weak annotation] selected in - annotation?.selected = selected + annotationView.onSelect = { [weak annotation] _ in annotation?.setNeedsUpdateSize() } self.annotation = annotation diff --git a/Sources/Examples/SwiftUI Examples/ViewAnnotationsExample.swift b/Sources/Examples/SwiftUI Examples/ViewAnnotationsExample.swift index b36e33e75439..08df10318c81 100644 --- a/Sources/Examples/SwiftUI Examples/ViewAnnotationsExample.swift +++ b/Sources/Examples/SwiftUI Examples/ViewAnnotationsExample.swift @@ -28,7 +28,7 @@ struct ViewAnnotationsExample: View { } } .allowOverlap(allowOverlap) - .selected(selected) + .priority(1) // Dynamic view annotations, appeared on tap. // The anchor can point to bottom, top, left, or right direction. @@ -48,6 +48,8 @@ struct ViewAnnotationsExample: View { guard let idx = taps.firstIndex(where: { $0.id == tap.id }) else { return } taps[idx].selectedAnchor = config } + .priority(-1) + .minZoom(5) } // A Dynamic View Annotation annotation, that is attached to the Polyline annotation. @@ -78,7 +80,8 @@ struct ViewAnnotationsExample: View { .allowZElevate(allowZElevate) .variableAnchors(.all) // Allow all directions for anchor .onAnchorChanged { self.etaAnnotationAnchor = $0.anchor } - .selected(true) + .priority(2) + .minZoom(5) } .onMapTapGesture { context in taps.append(Tap(coordinate: context.coordinate)) diff --git a/Sources/MapboxMaps/Annotations/ViewAnnotation.swift b/Sources/MapboxMaps/Annotations/ViewAnnotation.swift index df63ea1d7138..cdec503bd4c7 100644 --- a/Sources/MapboxMaps/Annotations/ViewAnnotation.swift +++ b/Sources/MapboxMaps/Annotations/ViewAnnotation.swift @@ -108,11 +108,27 @@ public final class ViewAnnotation { /// Specifies if this view annotation is selected meaning it should be placed on top of others. /// /// The property is `false` by default. + @available(*, deprecated, message: "Use priority instead.") public var selected: Bool { get { property(\.selected, default: false) } set { setProperty(\.selected, value: newValue, oldValue: selected) } } + /// Sorts annotations in descending order based on this value. + /// + /// A replacement for the deprecated `selected` field. + /// Simultaneous use of `priority` and `selected` fileds should be avoided. + /// Annotations with higher priority keys are drawn and placed first. + /// When equal priorities, less-anchor-options and least-recently-added sequentially used for annotations placement order. + /// `priority` field defaults to 0 when not set explicitly. + /// Negative, 0, positive values could be used in `priority` field. + /// + /// When updating existing annotations, if `priority` is not explicitly set, the current value will be retained. + public var priority: Int? { + get { options.priority } + set { setProperty(\.priority, value: newValue, oldValue: priority)} + } + /// A list of anchor configurations available. /// /// The annotation will automatically pick the first best anchor position depending on position @@ -181,6 +197,21 @@ public final class ViewAnnotation { } } + /// Minimum zoom value in range [0, 22] to display View Annotation. + /// If not provided or is out of range, defaults to 0. + public var minZoom: Double { + get { property(\.minZoom, default: 0) } + set { setProperty(\.minZoom, value: newValue, oldValue: minZoom) } + } + + /// Maximum zoom value in range [0, 22] to display View Annotation. + /// Should be greater than or equal to minZoom. + /// If not provided or is out of range, defaults to 22. + public var maxZoom: Double { + get { property(\.maxZoom, default: 22) } + set { setProperty(\.maxZoom, value: newValue, oldValue: maxZoom) } + } + let id = UUID().uuidString var isHidden = true { didSet { diff --git a/Sources/MapboxMaps/Annotations/ViewAnnotationOptions.swift b/Sources/MapboxMaps/Annotations/ViewAnnotationOptions.swift index 63352d1b6a15..c9e59a3e3d2f 100644 --- a/Sources/MapboxMaps/Annotations/ViewAnnotationOptions.swift +++ b/Sources/MapboxMaps/Annotations/ViewAnnotationOptions.swift @@ -47,6 +47,15 @@ public struct ViewAnnotationOptions: Equatable { /// If visible is null, default value `true` will be applied. public var visible: Bool? + /// A list of anchor configurations available. + /// + /// The annotation will automatically pick the first best anchor position depending on position + /// relative to other elements on the map. + /// + /// The ``ViewAnnotation/onAnchorChanged`` is called when the + /// effective position is updated. + /// + /// If not specified, the annotation will be placed in center. public var variableAnchors: [ViewAnnotationAnchorConfig]? /// Anchor describing where the view annotation will be located relatively to given geometry. @@ -66,13 +75,95 @@ public struct ViewAnnotationOptions: Equatable { /// Specifies if this view annotation is selected meaning it should be placed on top of others. /// If selected in null, default value `false` will be applied. + @available(*, deprecated, message: "Use priority instead.") public var selected: Bool? + /// Sorts annotations in descending order based on this value. + /// + /// A replacement for the deprecated `selected` field. + /// Simultaneous use of `priority` and `selected` fileds should be avoided. + /// Annotations with higher priority keys are drawn and placed first. + /// When equal priorities, less-anchor-options and least-recently-added sequentially used for annotations placement order. + /// `priority` field defaults to 0 when not set explicitly. + /// Negative, 0, positive values could be used in `priority` field. + /// + /// When updating existing annotations, if `priority` is not explicitly set, the current value will be retained. + public var priority: Int? + /// When `false`, the annotation will be displayed even if it go beyond camera padding. public var ignoreCameraPadding: Bool? + /// Minimum zoom value in range [0, 22] to display View Annotation. + /// If not provided or is out of range, defaults to 0. + public var minZoom: Double? + + /// Maximum zoom value in range [0, 22] to display View Annotation. + /// Should be greater than or equal to minZoom. + /// If not provided or is out of range, defaults to 22. + public var maxZoom: Double? + + /// Initializes a `ViewAnnotationOptions` + public init( + annotatedFeature: AnnotatedFeature? = nil, + width: CGFloat? = nil, + height: CGFloat? = nil, + allowOverlap: Bool? = nil, + allowOverlapWithPuck: Bool? = nil, + visible: Bool? = nil, + priority: Int? = nil, + variableAnchors: [ViewAnnotationAnchorConfig]? = nil, + ignoreCameraPadding: Bool? = nil, + minZoom: Double? = nil, + maxZoom: Double? = nil + ) { + self.init( + annotatedFeature: annotatedFeature, + width: width, + height: height, + allowOverlap: allowOverlap, + allowOverlapWithPuck: allowOverlapWithPuck, + visible: visible, + selected: nil, + priority: priority, + variableAnchors: variableAnchors, + ignoreCameraPadding: ignoreCameraPadding, + minZoom: minZoom, + maxZoom: maxZoom + ) + } + + @available(*, deprecated, message: "Use priority instead.") /// Initializes a `ViewAnnotationOptions` public init( + annotatedFeature: AnnotatedFeature? = nil, + width: CGFloat? = nil, + height: CGFloat? = nil, + allowOverlap: Bool? = nil, + allowOverlapWithPuck: Bool? = nil, + visible: Bool? = nil, + selected: Bool?, + variableAnchors: [ViewAnnotationAnchorConfig]? = nil, + ignoreCameraPadding: Bool? = nil, + minZoom: Double? = nil, + maxZoom: Double? = nil + ) { + self.init( + annotatedFeature: annotatedFeature, + width: width, + height: height, + allowOverlap: allowOverlap, + allowOverlapWithPuck: allowOverlapWithPuck, + visible: visible, + selected: selected, + priority: nil, + variableAnchors: variableAnchors, + ignoreCameraPadding: ignoreCameraPadding, + minZoom: minZoom, + maxZoom: maxZoom + ) + } + + private init( annotatedFeature: AnnotatedFeature? = nil, width: CGFloat? = nil, height: CGFloat? = nil, @@ -80,8 +171,11 @@ public struct ViewAnnotationOptions: Equatable { allowOverlapWithPuck: Bool? = nil, visible: Bool? = nil, selected: Bool? = nil, + priority: Int? = nil, variableAnchors: [ViewAnnotationAnchorConfig]? = nil, - ignoreCameraPadding: Bool? = nil + ignoreCameraPadding: Bool? = nil, + minZoom: Double? = nil, + maxZoom: Double? = nil ) { self.annotatedFeature = annotatedFeature self.width = width @@ -91,7 +185,10 @@ public struct ViewAnnotationOptions: Equatable { self.allowOverlapWithPuck = allowOverlapWithPuck self.visible = visible self.selected = selected + self.priority = priority self.ignoreCameraPadding = ignoreCameraPadding + self.minZoom = minZoom + self.maxZoom = maxZoom } /// Initializes a `ViewAnnotationOptions` with geometry. @@ -134,8 +231,11 @@ public struct ViewAnnotationOptions: Equatable { allowOverlapWithPuck: objcValue.__allowOverlapWithPuck?.boolValue, visible: objcValue.__visible?.boolValue, selected: objcValue.__selected?.boolValue, + priority: objcValue.__priority?.intValue, variableAnchors: objcValue.variableAnchors, - ignoreCameraPadding: objcValue.__ignoreCameraPadding?.boolValue + ignoreCameraPadding: objcValue.__ignoreCameraPadding?.boolValue, + minZoom: objcValue.__minZoom?.doubleValue, + maxZoom: objcValue.__maxZoom?.doubleValue ) } @@ -185,6 +285,10 @@ extension CoreViewAnnotationOptions { visible: swiftValue.visible as NSNumber?, variableAnchors: swiftValue.variableAnchors, selected: swiftValue.selected as NSNumber?, - ignoreCameraPadding: swiftValue.ignoreCameraPadding as NSNumber?) + priority: swiftValue.priority as NSNumber?, + ignoreCameraPadding: swiftValue.ignoreCameraPadding as NSNumber?, + minZoom: swiftValue.minZoom as NSNumber?, + maxZoom: swiftValue.maxZoom as NSNumber? + ) } } diff --git a/Sources/MapboxMaps/ContentBuilders/MapContent/MountedViewAnnotation.swift b/Sources/MapboxMaps/ContentBuilders/MapContent/MountedViewAnnotation.swift index 18727ccc3538..cbd3aff10f91 100644 --- a/Sources/MapboxMaps/ContentBuilders/MapContent/MountedViewAnnotation.swift +++ b/Sources/MapboxMaps/ContentBuilders/MapContent/MountedViewAnnotation.swift @@ -50,10 +50,13 @@ final class MountedViewAnnotation: MapContentMountedComponent { weakViewAnnotation?.ignoreCameraPadding = mapViewAnnotation.ignoreCameraPadding weakViewAnnotation?.visible = mapViewAnnotation.visible weakViewAnnotation?.selected = mapViewAnnotation.selected + weakViewAnnotation?.priority = mapViewAnnotation.priority weakViewAnnotation?.variableAnchors = mapViewAnnotation.variableAnchors weakViewAnnotation?.onAnchorChanged = mapViewAnnotation.actions.anchor weakViewAnnotation?.onVisibilityChanged = mapViewAnnotation.actions.visibility weakViewAnnotation?.onAnchorCoordinateChanged = mapViewAnnotation.actions.anchorCoordinate + weakViewAnnotation?.minZoom = mapViewAnnotation.minZoom + weakViewAnnotation?.maxZoom = mapViewAnnotation.maxZoom os_log(.debug, log: .contentDSL, "view annotation update %s", weakViewAnnotation?.id ?? "") } diff --git a/Sources/MapboxMaps/SwiftUI/Annotations/MapViewAnnotation.swift b/Sources/MapboxMaps/SwiftUI/Annotations/MapViewAnnotation.swift index 0533665008ca..d75772cbddea 100644 --- a/Sources/MapboxMaps/SwiftUI/Annotations/MapViewAnnotation.swift +++ b/Sources/MapboxMaps/SwiftUI/Annotations/MapViewAnnotation.swift @@ -31,6 +31,9 @@ public struct MapViewAnnotation { var visible = true var allowHitTesting = true var selected = false + var priority = 0 + var minZoom = 0.0 + var maxZoom = 22.0 var allowOverlapWithPuck = false var allowZElevate: Bool? var ignoreCameraPadding = false @@ -117,10 +120,25 @@ public struct MapViewAnnotation { } /// Specifies if this view annotation is selected meaning it should be placed on top of others. Defaults to `false`. + @available(*, deprecated, message: "Use priority instead.") public func selected(_ selected: Bool = false) -> MapViewAnnotation { with(self, setter(\.selected, selected)) } + /// Sorts annotations in descending order based on this value. + /// + /// A replacement for the deprecated `selected` field. + /// Simultaneous use of `priority` and `selected` fileds should be avoided. + /// Annotations with higher priority keys are drawn and placed first. + /// When equal priorities, less-anchor-options and least-recently-added sequentially used for annotations placement order. + /// `priority` field defaults to 0 when not set explicitly. + /// Negative, 0, positive values could be used in `priority` field. + /// + /// When updating existing annotations, if `priority` is not explicitly set, the current value will be retained. + public func priority(_ priority: Int) -> MapViewAnnotation { + with(self, setter(\.priority, priority)) + } + /// A list of anchor configurations available. /// /// The annotation will automatically pick the first best anchor position depending on position @@ -156,6 +174,19 @@ public struct MapViewAnnotation { public func onAnchorCoordinateChanged(action: @escaping (CLLocationCoordinate2D) -> Void) -> MapViewAnnotation { with(self, setter(\.actions.anchorCoordinate, action)) } + + /// Minimum zoom value in range [0, 22] to display View Annotation. + /// If not provided or is out of range, defaults to 0. + public func minZoom(_ minZoom: Double) -> MapViewAnnotation { + with(self, setter(\.minZoom, minZoom)) + } + + /// Maximum zoom value in range [0, 22] to display View Annotation. + /// Should be greater than or equal to minZoom. + /// If not provided or is out of range, defaults to 22. + public func maxZoom(_ maxZoom: Double) -> MapViewAnnotation { + with(self, setter(\.maxZoom, maxZoom)) + } } extension MapViewAnnotation: MapContent, PrimitiveMapContent { diff --git a/Tests/MapboxMapsTests/Annotations/ViewAnnotationOptionsTests.swift b/Tests/MapboxMapsTests/Annotations/ViewAnnotationOptionsTests.swift index 21588d2f0bb8..4d2d2bd3b0bd 100644 --- a/Tests/MapboxMapsTests/Annotations/ViewAnnotationOptionsTests.swift +++ b/Tests/MapboxMapsTests/Annotations/ViewAnnotationOptionsTests.swift @@ -15,7 +15,9 @@ final class ViewAnnotationOptionsTests: XCTestCase { let anchor: ViewAnnotationAnchor = .right let offsetX: CGFloat = 100.0 let offsetY: CGFloat = 200.0 - let selected: Bool = true + let priority: Int = 43 + let minZoom: Double = 10.0 + let maxZoom: Double = 20.0 var variableAnchors: [ViewAnnotationAnchorConfig] { [ViewAnnotationAnchorConfig(anchor: anchor, offsetX: offsetX, offsetY: offsetY)] } @@ -27,7 +29,7 @@ final class ViewAnnotationOptionsTests: XCTestCase { height: height, allowOverlap: allowOverlap, visible: visible, - selected: selected, + priority: priority, variableAnchors: variableAnchors) XCTAssertEqual(options.annotatedFeature, annotatedLayerFeature) @@ -38,7 +40,7 @@ final class ViewAnnotationOptionsTests: XCTestCase { XCTAssertEqual(options.variableAnchors?.first?.anchor, anchor) XCTAssertEqual(options.variableAnchors?.first?.offsetX, offsetX) XCTAssertEqual(options.variableAnchors?.first?.offsetY, offsetY) - XCTAssertEqual(options.selected, selected) + XCTAssertEqual(options.priority, priority) } func testCoreInit() { @@ -49,9 +51,12 @@ final class ViewAnnotationOptionsTests: XCTestCase { allowOverlap: allowOverlap, allowOverlapWithPuck: allowOverlapWithPuck, visible: visible, - selected: selected, + priority: priority, variableAnchors: [ViewAnnotationAnchorConfig(anchor: anchor, offsetX: offsetX, offsetY: offsetY)], - ignoreCameraPadding: ignoreCameraPadding) + ignoreCameraPadding: ignoreCameraPadding, + minZoom: minZoom, + maxZoom: maxZoom + ) let objcValue = CoreViewAnnotationOptions( __annotatedFeature: .fromGeometry(MapboxCommon.Geometry(point)), @@ -62,8 +67,11 @@ final class ViewAnnotationOptionsTests: XCTestCase { allowZElevate: allowZElevate as NSNumber?, visible: visible as NSNumber?, variableAnchors: variableAnchors, - selected: selected as NSNumber?, - ignoreCameraPadding: ignoreCameraPadding as NSNumber? + selected: nil, + priority: priority as NSNumber?, + ignoreCameraPadding: ignoreCameraPadding as NSNumber?, + minZoom: minZoom as NSNumber?, + maxZoom: maxZoom as NSNumber? ) let convertedOptions = ViewAnnotationOptions(objcValue) diff --git a/Tests/MapboxMapsTests/Annotations/ViewAnntoationTests.swift b/Tests/MapboxMapsTests/Annotations/ViewAnntoationTests.swift index 13034fa8cb50..24c0d95232c7 100644 --- a/Tests/MapboxMapsTests/Annotations/ViewAnntoationTests.swift +++ b/Tests/MapboxMapsTests/Annotations/ViewAnntoationTests.swift @@ -38,7 +38,7 @@ final class ViewAnnotationTests: XCTestCase { let va = ViewAnnotation(annotatedFeature: .geometry(point), view: view) va.allowOverlap = true va.visible = true - va.selected = true + va.priority = 4 va.allowZElevate = true let variableAnchors = [ViewAnnotationAnchorConfig(anchor: .bottom, offsetX: 10, offsetY: 20)] va.variableAnchors = variableAnchors @@ -47,7 +47,7 @@ final class ViewAnnotationTests: XCTestCase { XCTAssertEqual(va.allowOverlap, true) XCTAssertEqual(va.visible, true) - XCTAssertEqual(va.selected, true) + XCTAssertEqual(va.priority, 4) XCTAssertEqual(va.allowZElevate, true) // Add annotation @@ -66,7 +66,7 @@ final class ViewAnnotationTests: XCTestCase { XCTAssertEqual(addParameters.options.allowOverlapWithPuck, true) XCTAssertEqual(addParameters.options.allowZElevate, true) XCTAssertEqual(addParameters.options.ignoreCameraPadding, true) - XCTAssertEqual(addParameters.options.selected, true) + XCTAssertEqual(addParameters.options.priority, 4) XCTAssertEqual(addParameters.options.visible, true) XCTAssertEqual(addParameters.options.variableAnchors, variableAnchors) @@ -76,11 +76,11 @@ final class ViewAnnotationTests: XCTestCase { va.annotatedFeature = .layerFeature(layerId: "foo", featureId: "bar") va.allowOverlap = true // no update va.visible = false - va.selected = false + va.priority = -1 va.allowZElevate = false XCTAssertEqual(va.allowOverlap, true) XCTAssertEqual(va.visible, false) - XCTAssertEqual(va.selected, false) + XCTAssertEqual(va.priority, -1) XCTAssertEqual(va.allowZElevate, false) // no update without display link @@ -93,7 +93,7 @@ final class ViewAnnotationTests: XCTestCase { var expectedOptions = ViewAnnotationOptions( annotatedFeature: .layerFeature(layerId: "foo", featureId: "bar"), visible: false, - selected: false) + priority: -1) expectedOptions.allowZElevate = false XCTAssertEqual(updParameters.options, expectedOptions) @@ -117,7 +117,7 @@ final class ViewAnnotationTests: XCTestCase { XCTAssertEqual(addParameters2.options.height, actualSize.height) XCTAssertEqual(addParameters2.options.allowOverlap, true) XCTAssertEqual(addParameters2.options.allowZElevate, false) - XCTAssertEqual(addParameters2.options.selected, false) + XCTAssertEqual(addParameters2.options.priority, -1) XCTAssertEqual(addParameters2.options.visible, false) XCTAssertEqual(addParameters2.options.variableAnchors, variableAnchors) } diff --git a/Tests/MapboxMapsTests/Style/StyleIntegrationTests.swift b/Tests/MapboxMapsTests/Style/StyleIntegrationTests.swift index e1f8d266366c..dfc62a8be8a7 100644 --- a/Tests/MapboxMapsTests/Style/StyleIntegrationTests.swift +++ b/Tests/MapboxMapsTests/Style/StyleIntegrationTests.swift @@ -557,7 +557,9 @@ internal class StyleIntegrationTests: MapViewIntegrationTestCase { XCTAssertTrue(exaggerationTransitionProperty is NSNull) } - func testOnlyAddedDataIdReturned() { + func testOnlyAddedDataIdReturned() throws { + throw XCTSkip("Disabled due to behavior change, investigated in https://mapbox.atlassian.net/browse/MAPSIOS-1708") + let source = GeoJSONSource(id: "Source") let source2 = GeoJSONSource(id: "Source2") let geometry = Geometry.point(Point.init(LocationCoordinate2D(latitude: 0, longitude: 0))) diff --git a/scripts/api-compatibility-check/breakage_allowlist.txt b/scripts/api-compatibility-check/breakage_allowlist.txt index 2e7bd2a27887..455a50b6fde1 100644 --- a/scripts/api-compatibility-check/breakage_allowlist.txt +++ b/scripts/api-compatibility-check/breakage_allowlist.txt @@ -2054,3 +2054,6 @@ Var BackgroundPitchAlignment.viewport is now with @_spi #Update Standard and Standard Satellite config properties Func MapStyle.standard(theme:lightPreset:font:showPointOfInterestLabels:showTransitLabels:showPlaceLabels:showRoadLabels:show3dObjects:) has been renamed to Func standard(theme:lightPreset:font:showPointOfInterestLabels:showTransitLabels:showPlaceLabels:showRoadLabels:showPedestrianRoads:show3dObjects:colorMotorways:colorPlaceLabelHighlight:colorPlaceLabelSelect:colorRoads:colorTrunks:themeData:) Func MapStyle.standardSatellite(lightPreset:font:showPointOfInterestLabels:showTransitLabels:showPlaceLabels:showRoadLabels:showRoadsAndTransit:showPedestrianRoads:) has been renamed to Func standardSatellite(lightPreset:font:showPointOfInterestLabels:showTransitLabels:showPlaceLabels:showRoadLabels:showRoadsAndTransit:showPedestrianRoads:colorMotorways:colorPlaceLabelHighlight:colorPlaceLabelSelect:colorRoads:colorTrunks:) + +# Add ViewAnnotationOptions.min/maxZoom to the constructor +Constructor ViewAnnotationOptions.init(annotatedFeature:width:height:allowOverlap:allowOverlapWithPuck:visible:selected:variableAnchors:ignoreCameraPadding:) has been removed diff --git a/scripts/release/packager/versions.json b/scripts/release/packager/versions.json index a0355c0841ca..a9588d89c6a8 100644 --- a/scripts/release/packager/versions.json +++ b/scripts/release/packager/versions.json @@ -1,5 +1,5 @@ { - "MapboxCoreMaps": "11.9.0", - "MapboxCommon": "24.9.0", + "MapboxCoreMaps": "11.10.0-beta.2", + "MapboxCommon": "24.10.0-beta.2", "Turf": "4.0.0" } diff --git a/scripts/release/sync_deps_versions.sh b/scripts/release/sync_deps_versions.sh index dbf3592033e9..1e5ed155f6f8 100755 --- a/scripts/release/sync_deps_versions.sh +++ b/scripts/release/sync_deps_versions.sh @@ -25,6 +25,6 @@ sed -i '' -E "s/(.*MapsDependency.common.*):.*/\1: \"$COMMON_VERSION\"\)/" Pack info "Resolve SPM dependencies" swift package update -xcodebuild -resolvePackageDependencies -workspace Apps/Apps.xcworkspace -scheme MapboxMaps +xcodebuild -resolvePackageDependencies -project Examples.xcodeproj -scheme MapboxMaps finish "Updated dependency versions"