diff --git a/FuelBoard/StationDetailView.swift b/FuelBoard/StationDetailView.swift index 8eefea9..996b50a 100644 --- a/FuelBoard/StationDetailView.swift +++ b/FuelBoard/StationDetailView.swift @@ -118,58 +118,27 @@ struct StationDetailView: View { .accessibilityHint(String(localized: "Opens Apple Maps with driving directions", comment: "Accessibility hint for the tappable map preview in the More info sheet")) } - // Floating "Copied" confirmation: a capsule hovering over the - // bottom of the map, directly above the Address row and - // horizontally centred. It is an overlay, so nothing moves - // while it is up, and `allowsHitTesting(false)` keeps the - // map's tap target live underneath. The map's clipShape is - // applied BEFORE this, so the capsule is not clipped to the - // map's rounded rect. - .overlay(alignment: .bottom) { - if showingCopied { - HStack(spacing: 4) { - Image(systemName: "checkmark") - Text("Copied") - } - .font(.footnote.weight(.semibold)) - .foregroundStyle(.green) - .padding(.horizontal, 10) - .padding(.vertical, 6) - // A material base keeps it legible over map tiles: a - // 14% green wash alone (the notice-capsule recipe) - // vanishes against the map. - .background { - Capsule() - .fill(.regularMaterial) - .overlay(Capsule().fill(Color.green.opacity(0.22))) - } - .padding(.bottom, 12) - .allowsHitTesting(false) - .accessibilityHidden(true) - .transition(.opacity) - } - } // No hairline between the map and the Address row: the map // already reads as its own block, so the line only added // clutter. The Address/Distance and Distance/actions lines // stay. .listRowSeparator(.hidden, edges: .bottom) - // The map, the address, the distance, any notices and the two - // station actions all share ONE card. The list's own row - // hairlines separate them (inset, the same line that already - // separates Address from Distance), so no hand-rolled Divider is - // needed — adding one would double the line. - // The station name is NOT repeated here: the sheet header - // (navigationTitle, inline) already shows it, and the address - // line below has any leading repeat of the name stripped, so - // a "Name" row only said it twice. + // The map, the address, the distance, any notices and the two + // station actions all share ONE card (the list's own row + // hairlines separate them), so no hand-rolled Divider here — + // adding one would double the line. + // + // The station name is NOT repeated: the sheet header already + // shows it. // // The whole row is a copy control: it puts JUST the postcode // on the clipboard so it can be pasted into another // navigation app. The copy glyph sits ON the address line, - // and the "Copied" confirmation is a floating capsule over - // the map's bottom edge (see the map overlay above), so the - // confirmation can never reflow this row. + // and the "Copied" confirmation is a capsule that floats OVER + // THIS ROW — it confirms the address, so it must not hover + // over the map. It is an overlay, so nothing moves while it is + // up, and `allowsHitTesting(false)` keeps the row tappable + // through the capsule. Button { copyPostcode() } label: { @@ -195,6 +164,29 @@ struct StationDetailView: View { ? "" : String(localized: "Copies the postcode", comment: "Accessibility hint for the address row in the More info sheet")) + // Horizontally centred over the address line itself. + .overlay(alignment: .center) { + if showingCopied { + HStack(spacing: 4) { + Image(systemName: "checkmark") + Text("Copied") + } + .font(.footnote.weight(.semibold)) + .foregroundStyle(.green) + .padding(.horizontal, 10) + .padding(.vertical, 6) + // A material base keeps it legible where the tint + // alone (the notice-capsule recipe) washes out. + .background { + Capsule() + .fill(.regularMaterial) + .overlay(Capsule().fill(Color.green.opacity(0.22))) + } + .allowsHitTesting(false) + .accessibilityHidden(true) + .transition(.opacity) + } + } if let location { let distance = FuelStore.stationDistanceDisplay( station: station, userLat: location.lat, userLng: location.lng