diff --git a/docs/content/docs/components/map-view.mdx b/docs/content/docs/components/map-view.mdx index e342df4..dc3e5c5 100644 --- a/docs/content/docs/components/map-view.mdx +++ b/docs/content/docs/components/map-view.mdx @@ -59,9 +59,11 @@ mounting many live maps is expensive: not support cloud-based styling, so `mapId` is ignored on lite static maps. Lite mode caps its bitmap at ~2048px per dimension, so larger views (e.g. full-screen maps) fall back to a full map with all gestures disabled. -- **iOS (Apple)** - the base map is rendered with `MKMapSnapshotter`, which - loads entirely off the main thread (no live map view is ever created), so - static maps keep loading while scrolling. Markers stay live views +- **iOS (Apple)** - `MKMapSnapshotter` renders the base map off the main + thread, so static maps keep loading while scrolling. With nonzero + `edgeInsets`, a temporary `MKMapView` renders the image to keep Apple Maps + attribution inside the inset viewport. The map view is released after capture. + Markers stay live views positioned over the base map; polylines, polygons, circles, and ground overlays are drawn onto it. Tile overlays are not supported. - **iOS (Google)** - markers and shapes render as live overlay views, @@ -98,7 +100,8 @@ Notes: at the final camera (iOS) or re-centers (Android). Map-setting prop updates (e.g. `mapType`) after the snapshot are still ignored on iOS. - `edgeInsets` shift the visible center like on a live map, so the - coordinate centers in the inset viewport. Changing insets after the + coordinate centers in the inset viewport without changing the zoom. + On iOS, attribution also respects these insets. Changing insets after the render re-renders the base map (iOS) or re-centers the camera (Android). - For taps, wrap the map in a `Pressable` with `pointerEvents="none"` on the map container (as above) instead of relying on `onPress`. diff --git a/docs/content/docs/usage.mdx b/docs/content/docs/usage.mdx index dc25258..c70c8bc 100644 --- a/docs/content/docs/usage.mdx +++ b/docs/content/docs/usage.mdx @@ -105,6 +105,9 @@ Mounting many live maps is expensive. Use `staticMode` to render lightweight, no ``` +The example app uses the same markers and polyline in each static list map and its detail screen. +On iOS, both screens include a button to switch between Apple Maps and Google Maps. + Read more in [Static Maps](./components/map-view.mdx#static-maps). ## Next steps diff --git a/example/shared/src/screens/MarkerDetailScreen.tsx b/example/shared/src/screens/MarkerDetailScreen.tsx index aaf465f..a7840d4 100644 --- a/example/shared/src/screens/MarkerDetailScreen.tsx +++ b/example/shared/src/screens/MarkerDetailScreen.tsx @@ -1,11 +1,18 @@ -import { StyleSheet, View } from 'react-native'; -import { MapProvider, MapView, Marker } from '@lugg/maps'; +import { useState } from 'react'; +import { Platform, StyleSheet, View, useWindowDimensions } from 'react-native'; +import { MapProvider, MapView, Marker, type MapProviderType } from '@lugg/maps'; -import { ThemedText } from '../components'; +import { Button, ThemedText } from '../components'; import { INITIAL_MARKERS } from '../markers'; import { CIRCLE_CENTER } from '../mapData'; import { sizes, useTheme } from '../theme'; -import { PLACES } from './StaticMapsScreen'; +import { + PLACES, + PlaceConstellation, + PlaceMarkers, + fittedCamera, + placeCoordinates, +} from './StaticMapsScreen'; interface MarkerDetailScreenProps { name: string; @@ -18,7 +25,11 @@ const formatCoordinate = (value: number) => value.toFixed(4); export const MarkerDetailScreen = ({ name }: MarkerDetailScreenProps) => { const { colors } = useTheme(); + const { width, height } = useWindowDimensions(); const apiKey = process.env.GOOGLE_MAPS_API_KEY; + const [provider, setProvider] = useState( + Platform.OS === 'ios' ? 'apple' : 'google' + ); const marker = INITIAL_MARKERS.find((m) => m.name === name); const place = PLACES.find((p) => p.name === name); @@ -27,16 +38,26 @@ export const MarkerDetailScreen = ({ name }: MarkerDetailScreenProps) => { const title = marker?.title ?? place?.name ?? name; const description = marker?.description ?? place?.description ?? 'Marker detail screen'; + const camera = place + ? fittedCamera( + placeCoordinates(place), + provider, + { width, height: height - CARD_BOTTOM - CARD_HEIGHT }, + sizes.xl + ) + : { coordinate, zoom: 15 }; return ( { bottom: CARD_BOTTOM + CARD_HEIGHT, }} > - + {place ? ( + <> + + + + ) : ( + + )} +