From 7898052449390ffb4188b369a255647758516f0d Mon Sep 17 00:00:00 2001 From: David Feinzimer Date: Tue, 28 Feb 2023 12:21:07 -0800 Subject: [PATCH 01/21] Remove `onTapGesture` from compass --- Sources/ArcGISToolkit/Components/Compass/Compass.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/Sources/ArcGISToolkit/Components/Compass/Compass.swift b/Sources/ArcGISToolkit/Components/Compass/Compass.swift index b21456bd8..f2dbe9114 100644 --- a/Sources/ArcGISToolkit/Components/Compass/Compass.swift +++ b/Sources/ArcGISToolkit/Components/Compass/Compass.swift @@ -60,7 +60,6 @@ public struct Compass: View { } .aspectRatio(1, contentMode: .fit) .opacity(opacity) - .onTapGesture { heading = .zero } .frame(width: size, height: size) .onChange(of: heading) { _ in let newOpacity: Double = shouldHide ? .zero : 1 From 5ca7dba2b470e16602bb7fd77d7021e6ddbc0095 Mon Sep 17 00:00:00 2001 From: David Feinzimer Date: Tue, 28 Feb 2023 13:19:30 -0800 Subject: [PATCH 02/21] Update samples --- Examples/Examples/CompassExampleView.swift | 163 ++++++++++++++++++++- 1 file changed, 157 insertions(+), 6 deletions(-) diff --git a/Examples/Examples/CompassExampleView.swift b/Examples/Examples/CompassExampleView.swift index 137cf8808..a6d8e171a 100644 --- a/Examples/Examples/CompassExampleView.swift +++ b/Examples/Examples/CompassExampleView.swift @@ -15,7 +15,48 @@ import ArcGIS import ArcGISToolkit import SwiftUI +/// An example demonstrating how to use a compass in three different environments. struct CompassExampleView: View { + /// A scenario represents a type of environment a compass may be used in. + enum Scenario: CaseIterable { + case map + case sceneWithCamera + case sceneWithCameraController + + /// A human-readable label for the scenario. + var label: String { + switch self { + case .map: return "Map" + case .sceneWithCamera: return "Scene with camera" + case .sceneWithCameraController: return "Scene with camera controller" + } + } + } + + /// The active scenario. + @State private var scenario = Scenario.map + + var body: some View { + VStack { + switch scenario { + case.map: + MapWithViewpoint() + case .sceneWithCamera: + SceneWithCamera() + case .sceneWithCameraController: + SceneWithCameraController() + } + Picker("Scenario", selection: $scenario) { + ForEach(Scenario.allCases, id: \.self) { scen in + Text(scen.label) + } + } + } + } +} + +/// An example demonstrating how to use a compass with a map view. +struct MapWithViewpoint: View { /// The data model containing the `Map` displayed in the `MapView`. @StateObject private var dataModel = MapDataModel( map: Map(basemapStyle: .arcGISImagery) @@ -23,19 +64,129 @@ struct CompassExampleView: View { /// Allows for communication between the Compass and MapView or SceneView. @State private var viewpoint: Viewpoint? = Viewpoint( - center: Point(x: -117.19494, y: 34.05723, spatialReference: .wgs84), + center: .esriRedlands, scale: 10_000, rotation: -45 ) var body: some View { - MapView(map: dataModel.map, viewpoint: viewpoint) - .onViewpointChanged(kind: .centerAndScale) { viewpoint = $0 } - .overlay(alignment: .topTrailing) { - Compass(viewpoint: $viewpoint) + MapViewReader { mapViewProxy in + MapView(map: dataModel.map, viewpoint: viewpoint) + .onViewpointChanged(kind: .centerAndScale) { viewpoint = $0 } + .overlay(alignment: .topTrailing) { + Compass(viewpoint: $viewpoint) // Optionally provide a different size for the compass. - // .compassSize(size: <#T##CGFloat#>) + // .compassSize(size: T##CGFloat) + .padding() + .onTapGesture { + Task { + try? await mapViewProxy.setViewpointRotation(0) + } + } + } + } + } +} + +/// An example demonstrating how to use a compass with a scene view and camera. +struct SceneWithCamera: View { + /// The camera used by the scene view. + @State private var camera: Camera? = Camera( + lookingAt: .esriRedlands, + distance: 1_000, + heading: 45, + pitch: 45, + roll: .zero + ) + + /// The data model containing the `Scene` displayed in the `SceneView`. + @StateObject private var dataModel = SceneDataModel( + scene: Scene(basemapStyle: .arcGISImagery) + ) + + /// The current heading as reported by the scene view. + var heading: Binding { + Binding { + if let camera { + return camera.heading + } else { + return .zero + } + } set: { _ in + } + } + + var body: some View { + SceneViewReader { sceneViewProxy in + SceneView(scene: dataModel.scene, camera: $camera) + .overlay(alignment: .topTrailing) { + Compass(viewpointRotation: heading) + .padding() + .onTapGesture { + if let camera { + let newCamera = Camera( + location: camera.location, + heading: .zero, + pitch: camera.pitch, + roll: camera.roll + ) + Task { + try? await sceneViewProxy.setViewpointCamera( + newCamera, + duration: 0.3 + ) + } + } + } + } + } + } +} + +/// An example demonstrating how to use a compass with a scene view and camera controller. +struct SceneWithCameraController: View { + /// The data model containing the `Scene` displayed in the `SceneView`. + @StateObject private var dataModel = SceneDataModel( + scene: Scene(basemapStyle: .arcGISImagery) + ) + + /// The current heading as reported by the scene view. + @State private var heading: Double = .zero + + /// The orbit location camera controller used by the scene view. + private let cameraController = OrbitLocationCameraController( + targetPoint: .esriRedlands, + distance: 10_000 + )! + + var body: some View { + SceneView(scene: dataModel.scene, cameraController: cameraController) + .onCameraChanged { newCamera in + heading = newCamera.heading.rounded() + } + .overlay(alignment: .topTrailing) { + Compass(viewpointRotation: $heading) .padding() + .onTapGesture { + Task { + try? await cameraController.moveCamera( + distanceDelta: .zero, + headingDelta: heading > 180 ? 360 - heading : -heading, + pitchDelta: .zero, + duration: 0.3 + ) + } + } } } } + +private extension Point { + static var esriRedlands: Point { + .init( + x: -117.19494, + y: 34.05723, + spatialReference: .wgs84 + ) + } +} From 21b0a02e60809be825320f7e79a2192e85c811a4 Mon Sep 17 00:00:00 2001 From: David Feinzimer Date: Fri, 24 Mar 2023 11:32:14 -0700 Subject: [PATCH 03/21] Update branch --- Examples/Examples/CompassExampleView.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Examples/Examples/CompassExampleView.swift b/Examples/Examples/CompassExampleView.swift index a6d8e171a..a0f0495be 100644 --- a/Examples/Examples/CompassExampleView.swift +++ b/Examples/Examples/CompassExampleView.swift @@ -155,9 +155,9 @@ struct SceneWithCameraController: View { /// The orbit location camera controller used by the scene view. private let cameraController = OrbitLocationCameraController( - targetPoint: .esriRedlands, + target: .esriRedlands, distance: 10_000 - )! + ) var body: some View { SceneView(scene: dataModel.scene, cameraController: cameraController) From a6f8cfc6770583aedf90567368fd651a0d2f19be Mon Sep 17 00:00:00 2001 From: David Feinzimer Date: Mon, 27 Mar 2023 12:10:29 -0700 Subject: [PATCH 04/21] Simplify sample --- Examples/Examples/CompassExampleView.swift | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/Examples/Examples/CompassExampleView.swift b/Examples/Examples/CompassExampleView.swift index a0f0495be..eb230f664 100644 --- a/Examples/Examples/CompassExampleView.swift +++ b/Examples/Examples/CompassExampleView.swift @@ -57,10 +57,8 @@ struct CompassExampleView: View { /// An example demonstrating how to use a compass with a map view. struct MapWithViewpoint: View { - /// The data model containing the `Map` displayed in the `MapView`. - @StateObject private var dataModel = MapDataModel( - map: Map(basemapStyle: .arcGISImagery) - ) + /// The `Map` displayed in the `MapView`. + @State private var map = Map(basemapStyle: .arcGISImagery) /// Allows for communication between the Compass and MapView or SceneView. @State private var viewpoint: Viewpoint? = Viewpoint( @@ -71,12 +69,10 @@ struct MapWithViewpoint: View { var body: some View { MapViewReader { mapViewProxy in - MapView(map: dataModel.map, viewpoint: viewpoint) + MapView(map: map, viewpoint: viewpoint) .onViewpointChanged(kind: .centerAndScale) { viewpoint = $0 } .overlay(alignment: .topTrailing) { Compass(viewpoint: $viewpoint) - // Optionally provide a different size for the compass. - // .compassSize(size: T##CGFloat) .padding() .onTapGesture { Task { @@ -146,12 +142,10 @@ struct SceneWithCamera: View { /// An example demonstrating how to use a compass with a scene view and camera controller. struct SceneWithCameraController: View { /// The data model containing the `Scene` displayed in the `SceneView`. - @StateObject private var dataModel = SceneDataModel( - scene: Scene(basemapStyle: .arcGISImagery) - ) + @State private var scene = Scene(basemapStyle: .arcGISImagery) /// The current heading as reported by the scene view. - @State private var heading: Double = .zero + @State private var heading = Double.zero /// The orbit location camera controller used by the scene view. private let cameraController = OrbitLocationCameraController( @@ -160,7 +154,7 @@ struct SceneWithCameraController: View { ) var body: some View { - SceneView(scene: dataModel.scene, cameraController: cameraController) + SceneView(scene: scene, cameraController: cameraController) .onCameraChanged { newCamera in heading = newCamera.heading.rounded() } From b7e130bc63bd10bdf56733d41b79773a3e177f14 Mon Sep 17 00:00:00 2001 From: David Feinzimer Date: Mon, 27 Mar 2023 12:33:51 -0700 Subject: [PATCH 05/21] Remove `SceneWithCamera` sample --- Examples/Examples/CompassExampleView.swift | 98 ++++------------------ 1 file changed, 16 insertions(+), 82 deletions(-) diff --git a/Examples/Examples/CompassExampleView.swift b/Examples/Examples/CompassExampleView.swift index eb230f664..471e4596d 100644 --- a/Examples/Examples/CompassExampleView.swift +++ b/Examples/Examples/CompassExampleView.swift @@ -20,14 +20,12 @@ struct CompassExampleView: View { /// A scenario represents a type of environment a compass may be used in. enum Scenario: CaseIterable { case map - case sceneWithCamera case sceneWithCameraController /// A human-readable label for the scenario. var label: String { switch self { case .map: return "Map" - case .sceneWithCamera: return "Scene with camera" case .sceneWithCameraController: return "Scene with camera controller" } } @@ -41,8 +39,6 @@ struct CompassExampleView: View { switch scenario { case.map: MapWithViewpoint() - case .sceneWithCamera: - SceneWithCamera() case .sceneWithCameraController: SceneWithCameraController() } @@ -68,74 +64,12 @@ struct MapWithViewpoint: View { ) var body: some View { - MapViewReader { mapViewProxy in - MapView(map: map, viewpoint: viewpoint) - .onViewpointChanged(kind: .centerAndScale) { viewpoint = $0 } - .overlay(alignment: .topTrailing) { - Compass(viewpoint: $viewpoint) - .padding() - .onTapGesture { - Task { - try? await mapViewProxy.setViewpointRotation(0) - } - } - } - } - } -} - -/// An example demonstrating how to use a compass with a scene view and camera. -struct SceneWithCamera: View { - /// The camera used by the scene view. - @State private var camera: Camera? = Camera( - lookingAt: .esriRedlands, - distance: 1_000, - heading: 45, - pitch: 45, - roll: .zero - ) - - /// The data model containing the `Scene` displayed in the `SceneView`. - @StateObject private var dataModel = SceneDataModel( - scene: Scene(basemapStyle: .arcGISImagery) - ) - - /// The current heading as reported by the scene view. - var heading: Binding { - Binding { - if let camera { - return camera.heading - } else { - return .zero + MapView(map: map, viewpoint: viewpoint) + .onViewpointChanged(kind: .centerAndScale) { viewpoint = $0 } + .overlay(alignment: .topTrailing) { + Compass(viewpoint: $viewpoint) + .padding() } - } set: { _ in - } - } - - var body: some View { - SceneViewReader { sceneViewProxy in - SceneView(scene: dataModel.scene, camera: $camera) - .overlay(alignment: .topTrailing) { - Compass(viewpointRotation: heading) - .padding() - .onTapGesture { - if let camera { - let newCamera = Camera( - location: camera.location, - heading: .zero, - pitch: camera.pitch, - roll: camera.roll - ) - Task { - try? await sceneViewProxy.setViewpointCamera( - newCamera, - duration: 0.3 - ) - } - } - } - } - } } } @@ -159,18 +93,18 @@ struct SceneWithCameraController: View { heading = newCamera.heading.rounded() } .overlay(alignment: .topTrailing) { - Compass(viewpointRotation: $heading) - .padding() - .onTapGesture { - Task { - try? await cameraController.moveCamera( - distanceDelta: .zero, - headingDelta: heading > 180 ? 360 - heading : -heading, - pitchDelta: .zero, - duration: 0.3 - ) - } + Compass( + viewpointRotation: $heading, + action: { + _ = try? await cameraController.moveCamera( + distanceDelta: .zero, + headingDelta: heading > 180 ? 360 - heading : -heading, + pitchDelta: .zero, + duration: 0.3 + ) } + ) + .padding() } } } From 6435d32c5b6cbcdf3d3c891615fb4bbebf28dfbb Mon Sep 17 00:00:00 2001 From: David Feinzimer Date: Mon, 27 Mar 2023 12:34:21 -0700 Subject: [PATCH 06/21] Add action to compass --- .../Components/Compass/Compass.swift | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/Sources/ArcGISToolkit/Components/Compass/Compass.swift b/Sources/ArcGISToolkit/Components/Compass/Compass.swift index f2dbe9114..4c22182db 100644 --- a/Sources/ArcGISToolkit/Components/Compass/Compass.swift +++ b/Sources/ArcGISToolkit/Components/Compass/Compass.swift @@ -21,9 +21,15 @@ public struct Compass: View { /// hide/show itself when the heading is `0`. private let autoHide: Bool + /// The last time the compass was tapped. + @State private var lastTapTime: Date? + /// The opacity of the compass. @State private var opacity: Double = .zero + /// An action to perform when the compass is tapped. + private var action: (() async -> Void)? + /// A Boolean value indicating whether the compass should hide based on the /// current heading and whether the compass automatically hides. var shouldHide: Bool { @@ -41,13 +47,16 @@ public struct Compass: View { /// direction toward true East, etc.). /// - Parameters: /// - heading: The heading of the compass. + /// - action: An action to perform when the compass is tapped. /// - autoHide: A Boolean value that determines whether the compass /// automatically hides itself when the heading is `0`. public init( heading: Binding, + action: (() async -> Void)? = nil, autoHide: Bool = true ) { _heading = heading + self.action = action self.autoHide = autoHide } @@ -61,6 +70,7 @@ public struct Compass: View { .aspectRatio(1, contentMode: .fit) .opacity(opacity) .frame(width: size, height: size) + .onAppear { opacity = shouldHide ? 0 : 1 } .onChange(of: heading) { _ in let newOpacity: Double = shouldHide ? .zero : 1 guard opacity != newOpacity else { return } @@ -68,8 +78,15 @@ public struct Compass: View { opacity = newOpacity } } - .onAppear { opacity = shouldHide ? 0 : 1 } + .onTapGesture { lastTapTime = .now } .accessibilityLabel("Compass, heading \(Int(heading.rounded())) degrees \(CompassDirection(heading).rawValue)") + .task(id: lastTapTime) { + if let action { + await action() + } else { + heading = .zero + } + } } } } @@ -81,10 +98,12 @@ public extension Compass { /// - Parameters: /// - viewpointRotation: The viewpoint rotation whose value determines the /// heading of the compass. + /// - action: An action to perform when the compass is tapped. /// - autoHide: A Boolean value that determines whether the compass /// automatically hides itself when the viewpoint rotation is 0 degrees. init( viewpointRotation: Binding, + action: (() async -> Void)? = nil, autoHide: Bool = true ) { let heading = Binding(get: { @@ -92,16 +111,18 @@ public extension Compass { }, set: { newHeading in viewpointRotation.wrappedValue = newHeading.isZero ? .zero : 360 - newHeading }) - self.init(heading: heading, autoHide: autoHide) + self.init(heading: heading, action: action, autoHide: autoHide) } /// Creates a compass with a binding to an optional viewpoint. /// - Parameters: /// - viewpoint: The viewpoint whose rotation determines the heading of the compass. + /// - action: An action to perform when the compass is tapped. /// - autoHide: A Boolean value that determines whether the compass automatically hides itself /// when the viewpoint's rotation is 0 degrees. init( viewpoint: Binding, + action: (() async -> Void)? = nil, autoHide: Bool = true ) { let viewpointRotation = Binding { @@ -114,7 +135,7 @@ public extension Compass { rotation: newViewpointRotation ) } - self.init(viewpointRotation: viewpointRotation, autoHide: autoHide) + self.init(viewpointRotation: viewpointRotation, action: action, autoHide: autoHide) } /// Define a custom size for the compass. From ad9015057bd0aa56ca7b901c28f1d45a314b15d8 Mon Sep 17 00:00:00 2001 From: David Feinzimer Date: Mon, 27 Mar 2023 12:48:14 -0700 Subject: [PATCH 07/21] Reorganize --- .../ArcGISToolkit/Components/Compass/Compass.swift | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Sources/ArcGISToolkit/Components/Compass/Compass.swift b/Sources/ArcGISToolkit/Components/Compass/Compass.swift index 4c22182db..d835c3fb7 100644 --- a/Sources/ArcGISToolkit/Components/Compass/Compass.swift +++ b/Sources/ArcGISToolkit/Components/Compass/Compass.swift @@ -17,10 +17,6 @@ import SwiftUI /// A `Compass` (alias North arrow) shows where north is in a `MapView` or /// `SceneView`. public struct Compass: View { - /// A Boolean value indicating whether the compass should automatically - /// hide/show itself when the heading is `0`. - private let autoHide: Bool - /// The last time the compass was tapped. @State private var lastTapTime: Date? @@ -28,16 +24,20 @@ public struct Compass: View { @State private var opacity: Double = .zero /// An action to perform when the compass is tapped. - private var action: (() async -> Void)? + private let action: (() async -> Void)? + + /// A Boolean value indicating whether the compass should automatically + /// hide/show itself when the heading is `0`. + private let autoHide: Bool /// A Boolean value indicating whether the compass should hide based on the /// current heading and whether the compass automatically hides. - var shouldHide: Bool { + private var shouldHide: Bool { (heading.isZero || heading.isNaN) && autoHide } /// The width and height of the compass. - var size: CGFloat = 44 + private var size: CGFloat = 44 /// The heading of the compass in degrees. @Binding private var heading: Double From 38c0f097627841c059c3fa2155b3d7c04ce0d8d1 Mon Sep 17 00:00:00 2001 From: David Feinzimer Date: Mon, 27 Mar 2023 12:53:26 -0700 Subject: [PATCH 08/21] Update Compass.swift --- Sources/ArcGISToolkit/Components/Compass/Compass.swift | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/Sources/ArcGISToolkit/Components/Compass/Compass.swift b/Sources/ArcGISToolkit/Components/Compass/Compass.swift index d835c3fb7..9d0648f7e 100644 --- a/Sources/ArcGISToolkit/Components/Compass/Compass.swift +++ b/Sources/ArcGISToolkit/Components/Compass/Compass.swift @@ -17,9 +17,6 @@ import SwiftUI /// A `Compass` (alias North arrow) shows where north is in a `MapView` or /// `SceneView`. public struct Compass: View { - /// The last time the compass was tapped. - @State private var lastTapTime: Date? - /// The opacity of the compass. @State private var opacity: Double = .zero @@ -78,15 +75,14 @@ public struct Compass: View { opacity = newOpacity } } - .onTapGesture { lastTapTime = .now } - .accessibilityLabel("Compass, heading \(Int(heading.rounded())) degrees \(CompassDirection(heading).rawValue)") - .task(id: lastTapTime) { + .onTapGesture { if let action { - await action() + Task { await action() } } else { heading = .zero } } + .accessibilityLabel("Compass, heading \(Int(heading.rounded())) degrees \(CompassDirection(heading).rawValue)") } } } From 13ebe9fe01610bf61ba8bc636138b9e80536020e Mon Sep 17 00:00:00 2001 From: David Feinzimer Date: Mon, 27 Mar 2023 13:11:39 -0700 Subject: [PATCH 09/21] Update CompassExampleView.swift --- Examples/Examples/CompassExampleView.swift | 37 ++++++++++++---------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/Examples/Examples/CompassExampleView.swift b/Examples/Examples/CompassExampleView.swift index 471e4596d..d318a727d 100644 --- a/Examples/Examples/CompassExampleView.swift +++ b/Examples/Examples/CompassExampleView.swift @@ -18,34 +18,39 @@ import SwiftUI /// An example demonstrating how to use a compass in three different environments. struct CompassExampleView: View { /// A scenario represents a type of environment a compass may be used in. - enum Scenario: CaseIterable { + enum Scenario: String { case map - case sceneWithCameraController - - /// A human-readable label for the scenario. - var label: String { - switch self { - case .map: return "Map" - case .sceneWithCameraController: return "Scene with camera controller" - } - } + case scene } /// The active scenario. @State private var scenario = Scenario.map var body: some View { - VStack { + Group { switch scenario { - case.map: + case .map: MapWithViewpoint() - case .sceneWithCameraController: + case .scene: SceneWithCameraController() } - Picker("Scenario", selection: $scenario) { - ForEach(Scenario.allCases, id: \.self) { scen in - Text(scen.label) + } + .toolbar { + ToolbarItem(placement: .navigationBarTrailing) { + Menu(scenario.rawValue.capitalized) { + Button { + scenario = .map + } label: { + Label("Map", systemImage: "map.fill") + } + + Button { + scenario = .scene + } label: { + Label("Scene", systemImage: "globe.americas.fill") + } } + .labelStyle(.titleAndIcon) } } } From e59a4f575b794450f93af2639f2f1edf552f99d7 Mon Sep 17 00:00:00 2001 From: David Feinzimer Date: Mon, 27 Mar 2023 13:19:58 -0700 Subject: [PATCH 10/21] Doc --- Documentation/Compass/README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Documentation/Compass/README.md b/Documentation/Compass/README.md index b0df66593..5fdd376c7 100644 --- a/Documentation/Compass/README.md +++ b/Documentation/Compass/README.md @@ -23,9 +23,10 @@ Compass: /// direction toward true East, etc.). /// - Parameters: /// - heading: The heading of the compass. + /// - action: An action to perform when the compass is tapped. /// - autoHide: A Boolean value that determines whether the compass /// automatically hides itself when the heading is `0`. - public init(heading: Binding, autoHide: Bool = true) + public init(heading: Binding, action: (() async -> Void)? = nil, autoHide: Bool = true) ``` ```swift @@ -35,18 +36,20 @@ Compass: /// - Parameters: /// - viewpointRotation: The viewpoint rotation whose value determines the /// heading of the compass. + /// - action: An action to perform when the compass is tapped. /// - autoHide: A Boolean value that determines whether the compass /// automatically hides itself when the viewpoint rotation is 0 degrees. - public init(viewpointRotation: Binding, autoHide: Bool = true) + public init(viewpointRotation: Binding, action: (() async -> Void)? = nil, autoHide: Bool = true) ``` ```swift /// Creates a compass with a binding to an optional viewpoint. /// - Parameters: /// - viewpoint: The viewpoint whose rotation determines the heading of the compass. + /// - action: An action to perform when the compass is tapped. /// - autoHide: A Boolean value that determines whether the compass automatically hides itself /// when the viewpoint's rotation is 0 degrees. - public init(viewpoint: Binding, autoHide: Bool = true) + public init(viewpoint: Binding, action: (() async -> Void)? = nil, autoHide: Bool = true) ``` `Compass` has the following modifier: From 4d91afe156b173ef7f308fa038b8cf94a4a6616f Mon Sep 17 00:00:00 2001 From: David Feinzimer Date: Mon, 27 Mar 2023 13:20:48 -0700 Subject: [PATCH 11/21] Update Compass.swift --- Sources/ArcGISToolkit/Components/Compass/Compass.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/ArcGISToolkit/Components/Compass/Compass.swift b/Sources/ArcGISToolkit/Components/Compass/Compass.swift index 9d0648f7e..fe96e703f 100644 --- a/Sources/ArcGISToolkit/Components/Compass/Compass.swift +++ b/Sources/ArcGISToolkit/Components/Compass/Compass.swift @@ -29,7 +29,7 @@ public struct Compass: View { /// A Boolean value indicating whether the compass should hide based on the /// current heading and whether the compass automatically hides. - private var shouldHide: Bool { + var shouldHide: Bool { (heading.isZero || heading.isNaN) && autoHide } From 3ef79b6baf239731da22b2f0d6f3355cae723199 Mon Sep 17 00:00:00 2001 From: Mark Dostal Date: Fri, 31 Mar 2023 12:12:18 -0500 Subject: [PATCH 12/21] Move autoHide to modifier (from initializers) make action capable of being a closure. --- Examples/Examples/CompassExampleView.swift | 36 ++++++++++--------- .../Components/Compass/Compass.swift | 25 +++++++------ 2 files changed, 35 insertions(+), 26 deletions(-) diff --git a/Examples/Examples/CompassExampleView.swift b/Examples/Examples/CompassExampleView.swift index d318a727d..3a69be441 100644 --- a/Examples/Examples/CompassExampleView.swift +++ b/Examples/Examples/CompassExampleView.swift @@ -69,12 +69,19 @@ struct MapWithViewpoint: View { ) var body: some View { - MapView(map: map, viewpoint: viewpoint) - .onViewpointChanged(kind: .centerAndScale) { viewpoint = $0 } - .overlay(alignment: .topTrailing) { - Compass(viewpoint: $viewpoint) + MapViewReader { proxy in + MapView(map: map, viewpoint: viewpoint) + .onViewpointChanged(kind: .centerAndScale) { viewpoint = $0 } + .overlay(alignment: .topTrailing) { + Compass(viewpoint: $viewpoint) { + _ = try? await proxy.setViewpoint( + viewpoint.withRotation(0), + duration: 0.25 + ) + } .padding() - } + } + } } } @@ -98,17 +105,14 @@ struct SceneWithCameraController: View { heading = newCamera.heading.rounded() } .overlay(alignment: .topTrailing) { - Compass( - viewpointRotation: $heading, - action: { - _ = try? await cameraController.moveCamera( - distanceDelta: .zero, - headingDelta: heading > 180 ? 360 - heading : -heading, - pitchDelta: .zero, - duration: 0.3 - ) - } - ) + Compass(viewpointRotation: $heading) { + _ = try? await cameraController.moveCamera( + distanceDelta: .zero, + headingDelta: heading > 180 ? 360 - heading : -heading, + pitchDelta: .zero, + duration: 0.3 + ) + } .padding() } } diff --git a/Sources/ArcGISToolkit/Components/Compass/Compass.swift b/Sources/ArcGISToolkit/Components/Compass/Compass.swift index fe96e703f..96aef9937 100644 --- a/Sources/ArcGISToolkit/Components/Compass/Compass.swift +++ b/Sources/ArcGISToolkit/Components/Compass/Compass.swift @@ -25,7 +25,7 @@ public struct Compass: View { /// A Boolean value indicating whether the compass should automatically /// hide/show itself when the heading is `0`. - private let autoHide: Bool + private var autoHide: Bool = true /// A Boolean value indicating whether the compass should hide based on the /// current heading and whether the compass automatically hides. @@ -49,12 +49,10 @@ public struct Compass: View { /// automatically hides itself when the heading is `0`. public init( heading: Binding, - action: (() async -> Void)? = nil, - autoHide: Bool = true + action: (() async -> Void)? = nil ) { _heading = heading self.action = action - self.autoHide = autoHide } public var body: some View { @@ -99,15 +97,14 @@ public extension Compass { /// automatically hides itself when the viewpoint rotation is 0 degrees. init( viewpointRotation: Binding, - action: (() async -> Void)? = nil, - autoHide: Bool = true + action: (() async -> Void)? = nil ) { let heading = Binding(get: { viewpointRotation.wrappedValue.isZero ? .zero : 360 - viewpointRotation.wrappedValue }, set: { newHeading in viewpointRotation.wrappedValue = newHeading.isZero ? .zero : 360 - newHeading }) - self.init(heading: heading, action: action, autoHide: autoHide) + self.init(heading: heading, action: action) } /// Creates a compass with a binding to an optional viewpoint. @@ -118,8 +115,7 @@ public extension Compass { /// when the viewpoint's rotation is 0 degrees. init( viewpoint: Binding, - action: (() async -> Void)? = nil, - autoHide: Bool = true + action: (() async -> Void)? = nil ) { let viewpointRotation = Binding { viewpoint.wrappedValue?.rotation ?? .nan @@ -131,7 +127,7 @@ public extension Compass { rotation: newViewpointRotation ) } - self.init(viewpointRotation: viewpointRotation, action: action, autoHide: autoHide) + self.init(viewpointRotation: viewpointRotation, action: action) } /// Define a custom size for the compass. @@ -141,4 +137,13 @@ public extension Compass { copy.size = size return copy } + + /// Specifies whether the ``Compass`` should automatically hide when the heading is 0. + /// - Parameter newAutomaticallyHides: A Boolean value indicating whether the compass should automatically + /// hide/show itself when the heading is `0`. + func automaticallyHides(_ newAutomaticallyHides: Bool) -> some View { + var copy = self + copy.autoHide = newAutomaticallyHides + return copy + } } From 2df154156621804071e3d23176e4c82b8aafd4d8 Mon Sep 17 00:00:00 2001 From: Mark Dostal Date: Fri, 31 Mar 2023 12:23:50 -0500 Subject: [PATCH 13/21] Tweak examples; add Viewpoint.withViewpoint method; update doc. --- Examples/Examples/CompassExampleView.swift | 5 ++- .../Components/Compass/Compass.swift | 5 --- .../ArcGISToolkit/Extensions/Viewpoint.swift | 35 +++++++++++++++++++ 3 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 Sources/ArcGISToolkit/Extensions/Viewpoint.swift diff --git a/Examples/Examples/CompassExampleView.swift b/Examples/Examples/CompassExampleView.swift index 3a69be441..ee7558a89 100644 --- a/Examples/Examples/CompassExampleView.swift +++ b/Examples/Examples/CompassExampleView.swift @@ -74,7 +74,9 @@ struct MapWithViewpoint: View { .onViewpointChanged(kind: .centerAndScale) { viewpoint = $0 } .overlay(alignment: .topTrailing) { Compass(viewpoint: $viewpoint) { - _ = try? await proxy.setViewpoint( + guard let viewpoint else { return } + // Animate the map view to zero when the compass is tapped. + _ = await proxy.setViewpoint( viewpoint.withRotation(0), duration: 0.25 ) @@ -106,6 +108,7 @@ struct SceneWithCameraController: View { } .overlay(alignment: .topTrailing) { Compass(viewpointRotation: $heading) { + // Animate the scene view when the compass is tapped. _ = try? await cameraController.moveCamera( distanceDelta: .zero, headingDelta: heading > 180 ? 360 - heading : -heading, diff --git a/Sources/ArcGISToolkit/Components/Compass/Compass.swift b/Sources/ArcGISToolkit/Components/Compass/Compass.swift index 96aef9937..5c26e6a92 100644 --- a/Sources/ArcGISToolkit/Components/Compass/Compass.swift +++ b/Sources/ArcGISToolkit/Components/Compass/Compass.swift @@ -45,8 +45,6 @@ public struct Compass: View { /// - Parameters: /// - heading: The heading of the compass. /// - action: An action to perform when the compass is tapped. - /// - autoHide: A Boolean value that determines whether the compass - /// automatically hides itself when the heading is `0`. public init( heading: Binding, action: (() async -> Void)? = nil @@ -93,8 +91,6 @@ public extension Compass { /// - viewpointRotation: The viewpoint rotation whose value determines the /// heading of the compass. /// - action: An action to perform when the compass is tapped. - /// - autoHide: A Boolean value that determines whether the compass - /// automatically hides itself when the viewpoint rotation is 0 degrees. init( viewpointRotation: Binding, action: (() async -> Void)? = nil @@ -111,7 +107,6 @@ public extension Compass { /// - Parameters: /// - viewpoint: The viewpoint whose rotation determines the heading of the compass. /// - action: An action to perform when the compass is tapped. - /// - autoHide: A Boolean value that determines whether the compass automatically hides itself /// when the viewpoint's rotation is 0 degrees. init( viewpoint: Binding, diff --git a/Sources/ArcGISToolkit/Extensions/Viewpoint.swift b/Sources/ArcGISToolkit/Extensions/Viewpoint.swift new file mode 100644 index 000000000..9bf0e397e --- /dev/null +++ b/Sources/ArcGISToolkit/Extensions/Viewpoint.swift @@ -0,0 +1,35 @@ +// Copyright 2023 Esri. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import ArcGIS + +public extension Viewpoint { + /// Creates a new viewpoint with the same target geometry and scale but with a new rotation. + /// - Parameter rotation: The rotation for the new viewpoint. + /// - Returns: A new viewpoint. + func withRotation(_ rotation: Double) -> Viewpoint { + switch self.kind { + case .centerAndScale: + return Viewpoint( + center: self.targetGeometry as! Point, + scale: self.targetScale, + rotation: rotation + ) + case.boundingGeometry: + return Viewpoint( + boundingGeometry: self.targetGeometry, + rotation: rotation + ) + } + } +} From c16eb883c6ed0d5d3e928b5d0b4262d12fbc5ab7 Mon Sep 17 00:00:00 2001 From: Mark Dostal Date: Fri, 31 Mar 2023 14:17:00 -0500 Subject: [PATCH 14/21] Apply suggestions from code review Co-authored-by: David Feinzimer --- Documentation/Compass/README.md | 3 --- Examples/Examples/CompassExampleView.swift | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/Documentation/Compass/README.md b/Documentation/Compass/README.md index 5fdd376c7..b43e1d1d2 100644 --- a/Documentation/Compass/README.md +++ b/Documentation/Compass/README.md @@ -24,7 +24,6 @@ Compass: /// - Parameters: /// - heading: The heading of the compass. /// - action: An action to perform when the compass is tapped. - /// - autoHide: A Boolean value that determines whether the compass /// automatically hides itself when the heading is `0`. public init(heading: Binding, action: (() async -> Void)? = nil, autoHide: Bool = true) ``` @@ -37,7 +36,6 @@ Compass: /// - viewpointRotation: The viewpoint rotation whose value determines the /// heading of the compass. /// - action: An action to perform when the compass is tapped. - /// - autoHide: A Boolean value that determines whether the compass /// automatically hides itself when the viewpoint rotation is 0 degrees. public init(viewpointRotation: Binding, action: (() async -> Void)? = nil, autoHide: Bool = true) ``` @@ -47,7 +45,6 @@ Compass: /// - Parameters: /// - viewpoint: The viewpoint whose rotation determines the heading of the compass. /// - action: An action to perform when the compass is tapped. - /// - autoHide: A Boolean value that determines whether the compass automatically hides itself /// when the viewpoint's rotation is 0 degrees. public init(viewpoint: Binding, action: (() async -> Void)? = nil, autoHide: Bool = true) ``` diff --git a/Examples/Examples/CompassExampleView.swift b/Examples/Examples/CompassExampleView.swift index ee7558a89..cec42ea67 100644 --- a/Examples/Examples/CompassExampleView.swift +++ b/Examples/Examples/CompassExampleView.swift @@ -76,7 +76,7 @@ struct MapWithViewpoint: View { Compass(viewpoint: $viewpoint) { guard let viewpoint else { return } // Animate the map view to zero when the compass is tapped. - _ = await proxy.setViewpoint( + await proxy.setViewpoint( viewpoint.withRotation(0), duration: 0.25 ) From c2b6d55d6d2b7756a37ed8f97197a965e487307e Mon Sep 17 00:00:00 2001 From: Mark Dostal Date: Fri, 31 Mar 2023 14:26:40 -0500 Subject: [PATCH 15/21] update readme for new changes. --- Documentation/Compass/README.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/Documentation/Compass/README.md b/Documentation/Compass/README.md index b43e1d1d2..219912861 100644 --- a/Documentation/Compass/README.md +++ b/Documentation/Compass/README.md @@ -10,7 +10,8 @@ The ArcGIS Maps SDK for Swift currently supports rotating MapViews and SceneView Compass: -- Can be configured to automatically hide when the rotation is zero. +- Automatically hides when the rotation is zero. +- Can be configured to be always visible. - Will reset the map/scene rotation to North when tapped on. ## Key properties @@ -24,8 +25,7 @@ Compass: /// - Parameters: /// - heading: The heading of the compass. /// - action: An action to perform when the compass is tapped. - /// automatically hides itself when the heading is `0`. - public init(heading: Binding, action: (() async -> Void)? = nil, autoHide: Bool = true) + public init(heading: Binding, action: (() async -> Void)? = nil) ``` ```swift @@ -36,8 +36,7 @@ Compass: /// - viewpointRotation: The viewpoint rotation whose value determines the /// heading of the compass. /// - action: An action to perform when the compass is tapped. - /// automatically hides itself when the viewpoint rotation is 0 degrees. - public init(viewpointRotation: Binding, action: (() async -> Void)? = nil, autoHide: Bool = true) + public init(viewpointRotation: Binding, action: (() async -> Void)? = nil) ``` ```swift @@ -45,17 +44,17 @@ Compass: /// - Parameters: /// - viewpoint: The viewpoint whose rotation determines the heading of the compass. /// - action: An action to perform when the compass is tapped. - /// when the viewpoint's rotation is 0 degrees. - public init(viewpoint: Binding, action: (() async -> Void)? = nil, autoHide: Bool = true) + public init(viewpoint: Binding, action: (() async -> Void)? = nil) ``` -`Compass` has the following modifier: +`Compass` has the following modifiers: - `func compassSize(size: CGFloat)` - The size of the `Compass`, specifying both the width and height of the compass. +- `func automaticallyHides(newAutomaticallyHides: Bool)` - Specifies whether the ``Compass`` should automatically hide when the heading is 0. ## Behavior: -Whenever the map is not orientated North (non-zero bearing) the compass appears. When reset to north, it disappears. An initializer argument allows you to disable the auto-hide feature so that it always appears. +Whenever the map is not orientated North (non-zero bearing) the compass appears. When reset to north, it disappears. The `automaticallyHides` view modifier allows you to disable the auto-hide feature so that it is always displayed. When the compass is tapped, the map orients back to north (zero bearing). From 0a202c1e2ab23d7a28b1caffb69c1dca949f570f Mon Sep 17 00:00:00 2001 From: Mark Dostal Date: Fri, 31 Mar 2023 15:03:14 -0500 Subject: [PATCH 16/21] Fix tests; add Viewpoint tests --- Examples/Examples/CompassExampleView.swift | 1 - Tests/ArcGISToolkitTests/CompassTests.swift | 13 ++-- Tests/ArcGISToolkitTests/ViewpointTests.swift | 66 +++++++++++++++++++ 3 files changed, 74 insertions(+), 6 deletions(-) create mode 100644 Tests/ArcGISToolkitTests/ViewpointTests.swift diff --git a/Examples/Examples/CompassExampleView.swift b/Examples/Examples/CompassExampleView.swift index cec42ea67..0bc95e98c 100644 --- a/Examples/Examples/CompassExampleView.swift +++ b/Examples/Examples/CompassExampleView.swift @@ -50,7 +50,6 @@ struct CompassExampleView: View { Label("Scene", systemImage: "globe.americas.fill") } } - .labelStyle(.titleAndIcon) } } } diff --git a/Tests/ArcGISToolkitTests/CompassTests.swift b/Tests/ArcGISToolkitTests/CompassTests.swift index 9c8b8bb83..4b93de6b6 100644 --- a/Tests/ArcGISToolkitTests/CompassTests.swift +++ b/Tests/ArcGISToolkitTests/CompassTests.swift @@ -24,14 +24,15 @@ final class CompassTests: XCTestCase { let finalValue = 90.0 var _viewpoint: Viewpoint? = makeViewpoint(rotation: initialValue) let viewpoint = Binding(get: { _viewpoint }, set: { _viewpoint = $0 }) - let compass = Compass(viewpoint: viewpoint, autoHide: false) + let compass = Compass(viewpoint: viewpoint) + .automaticallyHides(false) as! Compass XCTAssertFalse(compass.shouldHide) _viewpoint = makeViewpoint(rotation: finalValue) XCTAssertFalse(compass.shouldHide) } /// Verifies that the compass accurately indicates when the compass should be hidden when - /// `autoHide` is `true`. + /// `autoHide` is `true` (which is the default). func testHiddenWithAutoHideOn() { let initialValue = 0.0 let finalValue = 90.0 @@ -51,8 +52,9 @@ final class CompassTests: XCTestCase { /// Verifies that the compass correctly initializes when given a `nil` viewpoint, and `autoHide` is /// `false`. - func testInitNoAutoHide() { - let compass = Compass(viewpoint: .constant(nil), autoHide: false) + func testAutomaticallyHidesNoAutoHide() { + let compass = Compass(viewpoint: .constant(nil)) + .automaticallyHides(false) as! Compass XCTAssertFalse(compass.shouldHide) } @@ -64,7 +66,8 @@ final class CompassTests: XCTestCase { /// Verifies that the compass correctly initializes when given only a viewpoint. func testInitWithViewpointAndAutoHide() { - let compass = Compass(viewpoint: .constant(makeViewpoint(rotation: .zero)), autoHide: false) + let compass = Compass(viewpoint: .constant(makeViewpoint(rotation: .zero))) + .automaticallyHides(false) as! Compass XCTAssertFalse(compass.shouldHide) } } diff --git a/Tests/ArcGISToolkitTests/ViewpointTests.swift b/Tests/ArcGISToolkitTests/ViewpointTests.swift new file mode 100644 index 000000000..b8a420a52 --- /dev/null +++ b/Tests/ArcGISToolkitTests/ViewpointTests.swift @@ -0,0 +1,66 @@ +// Copyright 2023 Esri. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import ArcGIS +import XCTest +@testable import ArcGISToolkit + +final class ViewpointTests: XCTestCase { + func testWithRotation() async { + let viewpoint = Viewpoint(center: .esriRedlands, scale: 15_000) + let expectedViewpoint = viewpoint.withRotation(45) + + XCTAssertEqual(expectedViewpoint.rotation, 45) + XCTAssertEqual(expectedViewpoint.targetScale, viewpoint.targetScale) + XCTAssertEqual(expectedViewpoint.targetGeometry, viewpoint.targetGeometry) + } + + func testWithRotationWithBoundingGeometry() { + let rotatedViewpoint = Viewpoint(boundingGeometry: Polyline.simple.extent, rotation: -45) + XCTAssertEqual(rotatedViewpoint.rotation, -45) + + let nonRotatedViewpoint = rotatedViewpoint.withRotation(.zero) + XCTAssertEqual(nonRotatedViewpoint.rotation, 0) + XCTAssertEqual(nonRotatedViewpoint.targetGeometry, rotatedViewpoint.targetGeometry) + } + + func testWithRotationWithCenterAndScale() { + let rotatedViewpoint = Viewpoint(center: .esriRedlands, scale: 1_000, rotation: 45) + XCTAssertEqual(rotatedViewpoint.rotation, 45) + + let nonRotatedViewpoint = rotatedViewpoint.withRotation(.zero) + XCTAssertEqual(nonRotatedViewpoint.rotation, 0) + XCTAssertEqual(nonRotatedViewpoint.targetScale, rotatedViewpoint.targetScale) + XCTAssertEqual(nonRotatedViewpoint.targetGeometry, rotatedViewpoint.targetGeometry) + } +} + +extension Point { + static var esriRedlands: Point { + .init( + x: -117.19494, + y: 34.05723, + spatialReference: .wgs84 + ) + } +} + +private extension Polyline { + static var simple: Polyline { + .init(points: [ + Point(x: -117, y: 34, spatialReference: .wgs84), + Point(x: -116, y: 34, spatialReference: .wgs84), + Point(x: -116, y: 33, spatialReference: .wgs84) + ]) + } +} From a759615e75c24580bda5707962eaf5f8d50fe37f Mon Sep 17 00:00:00 2001 From: Mark Dostal Date: Fri, 31 Mar 2023 15:09:14 -0500 Subject: [PATCH 17/21] PR review change for argument name. --- Sources/ArcGISToolkit/Components/Compass/Compass.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/ArcGISToolkit/Components/Compass/Compass.swift b/Sources/ArcGISToolkit/Components/Compass/Compass.swift index 5c26e6a92..b7a466971 100644 --- a/Sources/ArcGISToolkit/Components/Compass/Compass.swift +++ b/Sources/ArcGISToolkit/Components/Compass/Compass.swift @@ -134,11 +134,11 @@ public extension Compass { } /// Specifies whether the ``Compass`` should automatically hide when the heading is 0. - /// - Parameter newAutomaticallyHides: A Boolean value indicating whether the compass should automatically + /// - Parameter flag: A Boolean value indicating whether the compass should automatically /// hide/show itself when the heading is `0`. - func automaticallyHides(_ newAutomaticallyHides: Bool) -> some View { + func automaticallyHides(_ flag: Bool) -> some View { var copy = self - copy.autoHide = newAutomaticallyHides + copy.autoHide = flag return copy } } From a067be95d52c0763107ca94cd6da40074fd13505 Mon Sep 17 00:00:00 2001 From: Mark Dostal Date: Sat, 1 Apr 2023 14:35:12 -0500 Subject: [PATCH 18/21] Make compass action synchronous. --- Examples/Examples/CompassExampleView.swift | 26 +++++++++++-------- .../Components/Compass/Compass.swift | 10 +++---- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/Examples/Examples/CompassExampleView.swift b/Examples/Examples/CompassExampleView.swift index 0bc95e98c..21916f3a0 100644 --- a/Examples/Examples/CompassExampleView.swift +++ b/Examples/Examples/CompassExampleView.swift @@ -74,11 +74,13 @@ struct MapWithViewpoint: View { .overlay(alignment: .topTrailing) { Compass(viewpoint: $viewpoint) { guard let viewpoint else { return } - // Animate the map view to zero when the compass is tapped. - await proxy.setViewpoint( - viewpoint.withRotation(0), - duration: 0.25 - ) + Task { + // Animate the map view to zero when the compass is tapped. + await proxy.setViewpoint( + viewpoint.withRotation(0), + duration: 0.25 + ) + } } .padding() } @@ -108,12 +110,14 @@ struct SceneWithCameraController: View { .overlay(alignment: .topTrailing) { Compass(viewpointRotation: $heading) { // Animate the scene view when the compass is tapped. - _ = try? await cameraController.moveCamera( - distanceDelta: .zero, - headingDelta: heading > 180 ? 360 - heading : -heading, - pitchDelta: .zero, - duration: 0.3 - ) + Task { + _ = try? await cameraController.moveCamera( + distanceDelta: .zero, + headingDelta: heading > 180 ? 360 - heading : -heading, + pitchDelta: .zero, + duration: 0.3 + ) + } } .padding() } diff --git a/Sources/ArcGISToolkit/Components/Compass/Compass.swift b/Sources/ArcGISToolkit/Components/Compass/Compass.swift index b7a466971..80886c17a 100644 --- a/Sources/ArcGISToolkit/Components/Compass/Compass.swift +++ b/Sources/ArcGISToolkit/Components/Compass/Compass.swift @@ -21,7 +21,7 @@ public struct Compass: View { @State private var opacity: Double = .zero /// An action to perform when the compass is tapped. - private let action: (() async -> Void)? + private let action: (() -> Void)? /// A Boolean value indicating whether the compass should automatically /// hide/show itself when the heading is `0`. @@ -47,7 +47,7 @@ public struct Compass: View { /// - action: An action to perform when the compass is tapped. public init( heading: Binding, - action: (() async -> Void)? = nil + action: (() -> Void)? = nil ) { _heading = heading self.action = action @@ -73,7 +73,7 @@ public struct Compass: View { } .onTapGesture { if let action { - Task { await action() } + action() } else { heading = .zero } @@ -93,7 +93,7 @@ public extension Compass { /// - action: An action to perform when the compass is tapped. init( viewpointRotation: Binding, - action: (() async -> Void)? = nil + action: (() -> Void)? = nil ) { let heading = Binding(get: { viewpointRotation.wrappedValue.isZero ? .zero : 360 - viewpointRotation.wrappedValue @@ -110,7 +110,7 @@ public extension Compass { /// when the viewpoint's rotation is 0 degrees. init( viewpoint: Binding, - action: (() async -> Void)? = nil + action: (() -> Void)? = nil ) { let viewpointRotation = Binding { viewpoint.wrappedValue?.rotation ?? .nan From 64d9acc237060a8b70c3bc54926d2e6c7d72dabc Mon Sep 17 00:00:00 2001 From: Mark Dostal Date: Sat, 1 Apr 2023 14:35:43 -0500 Subject: [PATCH 19/21] Remove `rawValue` from Item.id constructor. --- Examples/Examples/PopupExampleView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/Examples/PopupExampleView.swift b/Examples/Examples/PopupExampleView.swift index 648fdfa36..bed264ab1 100644 --- a/Examples/Examples/PopupExampleView.swift +++ b/Examples/Examples/PopupExampleView.swift @@ -19,7 +19,7 @@ struct PopupExampleView: View { static func makeMap() -> Map { let portalItem = PortalItem( portal: .arcGISOnline(connection: .anonymous), - id: Item.ID(rawValue: "9f3a674e998f461580006e626611f9ad")! + id: Item.ID("9f3a674e998f461580006e626611f9ad")! ) return Map(item: portalItem) } From 6788766059bc17d579ac93d02ef10240fea4c5f0 Mon Sep 17 00:00:00 2001 From: Mark Dostal Date: Sat, 1 Apr 2023 14:36:56 -0500 Subject: [PATCH 20/21] Apply suggestions from code review Co-authored-by: David Feinzimer --- Documentation/Compass/README.md | 2 +- Sources/ArcGISToolkit/Components/Compass/Compass.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/Compass/README.md b/Documentation/Compass/README.md index 219912861..f9f241ce3 100644 --- a/Documentation/Compass/README.md +++ b/Documentation/Compass/README.md @@ -50,7 +50,7 @@ Compass: `Compass` has the following modifiers: - `func compassSize(size: CGFloat)` - The size of the `Compass`, specifying both the width and height of the compass. -- `func automaticallyHides(newAutomaticallyHides: Bool)` - Specifies whether the ``Compass`` should automatically hide when the heading is 0. +- `func automaticallyHides(_:)` - Specifies whether the ``Compass`` should automatically hide when the heading is 0. ## Behavior: diff --git a/Sources/ArcGISToolkit/Components/Compass/Compass.swift b/Sources/ArcGISToolkit/Components/Compass/Compass.swift index 80886c17a..45cd76a96 100644 --- a/Sources/ArcGISToolkit/Components/Compass/Compass.swift +++ b/Sources/ArcGISToolkit/Components/Compass/Compass.swift @@ -134,7 +134,7 @@ public extension Compass { } /// Specifies whether the ``Compass`` should automatically hide when the heading is 0. - /// - Parameter flag: A Boolean value indicating whether the compass should automatically + /// - Parameter flag: A Boolean value indicating whether the compass should automatically /// hide/show itself when the heading is `0`. func automaticallyHides(_ flag: Bool) -> some View { var copy = self From 2bc8a8cb777a25f810bf935a38cb8a5887b1d3b0 Mon Sep 17 00:00:00 2001 From: Mark Dostal Date: Mon, 3 Apr 2023 11:25:20 -0500 Subject: [PATCH 21/21] Apply suggestions from code review Co-authored-by: David Feinzimer --- Documentation/Compass/README.md | 6 +++--- Examples/Examples/CompassExampleView.swift | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/Compass/README.md b/Documentation/Compass/README.md index f9f241ce3..f2cc89e93 100644 --- a/Documentation/Compass/README.md +++ b/Documentation/Compass/README.md @@ -25,7 +25,7 @@ Compass: /// - Parameters: /// - heading: The heading of the compass. /// - action: An action to perform when the compass is tapped. - public init(heading: Binding, action: (() async -> Void)? = nil) + public init(heading: Binding, action: (() -> Void)? = nil) ``` ```swift @@ -36,7 +36,7 @@ Compass: /// - viewpointRotation: The viewpoint rotation whose value determines the /// heading of the compass. /// - action: An action to perform when the compass is tapped. - public init(viewpointRotation: Binding, action: (() async -> Void)? = nil) + public init(viewpointRotation: Binding, action: (() -> Void)? = nil) ``` ```swift @@ -44,7 +44,7 @@ Compass: /// - Parameters: /// - viewpoint: The viewpoint whose rotation determines the heading of the compass. /// - action: An action to perform when the compass is tapped. - public init(viewpoint: Binding, action: (() async -> Void)? = nil) + public init(viewpoint: Binding, action: (() -> Void)? = nil) ``` `Compass` has the following modifiers: diff --git a/Examples/Examples/CompassExampleView.swift b/Examples/Examples/CompassExampleView.swift index 21916f3a0..d92a3480c 100644 --- a/Examples/Examples/CompassExampleView.swift +++ b/Examples/Examples/CompassExampleView.swift @@ -111,7 +111,7 @@ struct SceneWithCameraController: View { Compass(viewpointRotation: $heading) { // Animate the scene view when the compass is tapped. Task { - _ = try? await cameraController.moveCamera( + await cameraController.moveCamera( distanceDelta: .zero, headingDelta: heading > 180 ? 360 - heading : -heading, pitchDelta: .zero,