@@ -29,97 +29,94 @@ struct AddFeaturesWithContingentValuesView: View {
2929 @State private var error : Error ?
3030
3131 var body : some View {
32- ZStack {
33- GeometryReader { geometryProxy in
34- MapViewReader { mapViewProxy in
35- MapView ( map: model. map, graphicsOverlays: [ model. graphicsOverlay] )
36- . onSingleTapGesture { _, mapPoint in
37- tapLocation = mapPoint
38- }
39- . task ( id: tapLocation) {
40- // Add a feature representing a bird's nest when the map is tapped.
41- guard let tapLocation else { return }
32+ GeometryReader { geometryProxy in
33+ MapViewReader { mapViewProxy in
34+ MapView ( map: model. map, graphicsOverlays: [ model. graphicsOverlay] )
35+ . onSingleTapGesture { _, mapPoint in
36+ tapLocation = mapPoint
37+ }
38+ . task ( id: tapLocation) {
39+ // Add a feature representing a bird's nest when the map is tapped.
40+ guard let tapLocation else { return }
41+
42+ do {
43+ try await model. addFeature ( at: tapLocation)
44+ addFeatureSheetIsPresented = true
4245
43- do {
44- try await model. addFeature ( at: tapLocation)
45- addFeatureSheetIsPresented = true
46-
47- // Create an envelope from the screen's frame.
48- let viewRect = geometryProxy. frame ( in: . local)
49- guard let viewExtent = mapViewProxy. envelope (
50- fromViewRect: viewRect
51- ) else { return }
52-
53- // Update the map's viewpoint with an offsetted tap location
54- // to center the feature in the top half of the screen.
55- let yOffset = ( viewExtent. height / 2 ) / 2
56- let newViewpointCenter = Point (
57- x: tapLocation. x,
58- y: tapLocation. y - yOffset
59- )
60- await mapViewProxy. setViewpointCenter ( newViewpointCenter)
61- } catch {
62- self . error = error
63- }
64- }
65- . task {
66- do {
67- // Load the features from the geodatabase when the sample loads.
68- try await model. loadFeatures ( )
69-
70- // Zoom to the extent of the added layer.
71- guard let extent = model. map. operationalLayers. first? . fullExtent
72- else { return }
73- await mapViewProxy. setViewpointGeometry ( extent, padding: 15 )
74- } catch {
75- self . error = error
76- }
77- }
78- }
79- }
80-
81- VStack {
82- Spacer ( )
83-
84- // A button that allows the popover to display.
85- Button ( " " ) { }
86- . opacity ( 0 )
87- . popover ( isPresented: $addFeatureSheetIsPresented) {
88- NavigationStack {
89- AddFeatureView ( model: model)
90- . navigationTitle ( " Add Bird Nest " )
91- . navigationBarTitleDisplayMode ( . inline)
92- . toolbar {
93- ToolbarItem ( placement: . cancellationAction) {
94- Button ( " Cancel " , role: . cancel) {
95- addFeatureSheetIsPresented = false
96- }
97- }
98-
99- ToolbarItem ( placement: . confirmationAction) {
100- Button ( " Done " ) {
101- model. feature = nil
102- addFeatureSheetIsPresented = false
103- }
104- . disabled ( !model. contingenciesAreValid)
105- }
106- }
46+ // Create an envelope from the screen's frame.
47+ let viewRect = geometryProxy. frame ( in: . local)
48+ guard let viewExtent = mapViewProxy. envelope (
49+ fromViewRect: viewRect
50+ ) else { return }
51+
52+ // Update the map's viewpoint with an offsetted tap location
53+ // to center the feature in the top half of the screen.
54+ let yOffset = ( viewExtent. height / 2 ) / 2
55+ let newViewpointCenter = Point (
56+ x: tapLocation. x,
57+ y: tapLocation. y - yOffset
58+ )
59+ await mapViewProxy. setViewpointCenter ( newViewpointCenter)
60+ } catch {
61+ self . error = error
10762 }
108- . presentationDetents ( [ . fraction( 0.5 ) ] )
109- . frame ( idealWidth: 320 , idealHeight: 320 )
11063 }
111- . task ( id: addFeatureSheetIsPresented) {
112- // When the sheet closes, remove the feature if it is invalid.
113- guard !addFeatureSheetIsPresented, model. feature != nil else { return }
114-
64+ . task {
11565 do {
116- try await model. removeFeature ( )
66+ // Load the features from the geodatabase when the sample loads.
67+ try await model. loadFeatures ( )
68+
69+ // Zoom to the extent of the added layer.
70+ guard let extent = model. map. operationalLayers. first? . fullExtent
71+ else { return }
72+ await mapViewProxy. setViewpointGeometry ( extent, padding: 15 )
11773 } catch {
11874 self . error = error
11975 }
12076 }
12177 }
12278 }
79+ . overlay ( alignment: . bottom) {
80+ // A workaround that allows the popover to display at the bottom of
81+ // the screen on Mac Catalyst.
82+ EmptyView ( )
83+ . frame ( width: 1 , height: 1 )
84+ . padding ( )
85+ . popover ( isPresented: $addFeatureSheetIsPresented, arrowEdge: . bottom) {
86+ NavigationStack {
87+ AddFeatureView ( model: model)
88+ . navigationTitle ( " Add Bird Nest " )
89+ . navigationBarTitleDisplayMode ( . inline)
90+ . toolbar {
91+ ToolbarItem ( placement: . cancellationAction) {
92+ Button ( " Cancel " , role: . cancel) {
93+ addFeatureSheetIsPresented = false
94+ }
95+ }
96+
97+ ToolbarItem ( placement: . confirmationAction) {
98+ Button ( " Done " ) {
99+ model. feature = nil
100+ addFeatureSheetIsPresented = false
101+ }
102+ . disabled ( !model. contingenciesAreValid)
103+ }
104+ }
105+ }
106+ . presentationDetents ( [ . fraction( 0.5 ) ] )
107+ . frame ( idealWidth: 320 , idealHeight: 320 )
108+ }
109+ . task ( id: addFeatureSheetIsPresented) {
110+ // When the sheet closes, remove the feature if it is invalid.
111+ guard !addFeatureSheetIsPresented, model. feature != nil else { return }
112+
113+ do {
114+ try await model. removeFeature ( )
115+ } catch {
116+ self . error = error
117+ }
118+ }
119+ }
123120 . errorAlert ( presentingError: $error)
124121 }
125122}
0 commit comments