Skip to main content

UI controls

Map​

All SDK distributions contain a standard set of React components for controlling the map. Add the components over MapView in a regular React Native layout and pass them the map instance from MapController.

The standard set includes:

  1. IndoorControl to switch floors.
  2. TrafficControl to display the traffic level and manage the visibility of traffic jams on the map.
  3. ZoomControl to scale the map.
  4. CompassControl to display the current map rotation angle relative to the north.
  5. MyLocationControl to fly to the current user location.
  6. CopyrightControl to display copyright inside MapView. The copyright appears automatically, you can configure its position using the copyrightAlignment and copyrightEdgeInsets properties of MapViewProps.
import React from 'react';
import { StyleSheet, View } from 'react-native';
import {
CompassControl,
IndoorControl,
MapView,
MyLocationControl,
TrafficControl,
ZoomControl,
type MapControllerState,
} from '@2gis/dgis-mobile-sdk-full';

export function MapWithControls({
controllerState,
requestLocationPermission,
}: {
controllerState: MapControllerState;
requestLocationPermission: () => void;
}) {
const map =
controllerState.status === 'ready' ? controllerState.controller.map : null;

return (
<View style={styles.root}>
<MapView controllerState={controllerState} style={styles.map} />
{map !== null && (
<>
<View style={styles.rightControls}>
<TrafficControl map={map} />
<CompassControl map={map} />
<ZoomControl map={map} />
</View>
<View style={styles.leftControls}>
<IndoorControl map={map} />
<MyLocationControl
map={map}
onPermissionRequest={requestLocationPermission}
/>
</View>
</>
)}
</View>
);
}

const styles = StyleSheet.create({
root: { flex: 1 },
map: { flex: 1 },
rightControls: {
position: 'absolute',
right: 16,
bottom: 32,
gap: 8,
},
leftControls: {
position: 'absolute',
left: 16,
bottom: 32,
gap: 8,
},
});

To change the component colors, use the SDK factories:

import {
makeTrafficControlColors,
makeZoomControlColors,
} from '@2gis/dgis-mobile-sdk-full';

const palette = {
background: '#1F2937',
transparentBackground: 'rgba(31,41,55,0.6)',
primaryContent: '#FFFFFF',
tertiaryContent: '#9CA3AF',
quaternaryContent: '#4B5563',
activeContent: '#38BDF8',
lowAlert: '#22C55E',
mediumAlert: '#F59E0B',
highAlert: '#EF4444',
};

<TrafficControl map={map} colors={makeTrafficControlColors(palette)} />;
<ZoomControl map={map} colors={makeZoomControlColors(palette)} />;

Directory​

The current React Native SDK does not export a ready-made search widget. You can implement a search bar and a result list in the application using SearchManager.suggest() and SearchManager.search().

import React, { useEffect, useMemo, useRef, useState } from 'react';
import { FlatList, Text, TextInput, View } from 'react-native';
import {
SearchManager,
SuggestQueryBuilder,
type Context,
type Suggest,
} from '@2gis/dgis-mobile-sdk-full';

export function SearchBox({ context }: { context: Context }) {
const searchManager = useMemo(
() => SearchManager.createOnlineManager(context),
[context],
);
const [suggests, setSuggests] = useState<Suggest[]>([]);
const futureRef = useRef<ReturnType<SearchManager['suggest']> | null>(null);

useEffect(() => {
return () => {
futureRef.current?.destroy();
searchManager.destroy();
};
}, [searchManager]);

const onChangeText = (text: string) => {
if (text.trim() === '') {
setSuggests([]);
return;
}

futureRef.current?.destroy();

const query = SuggestQueryBuilder.fromQueryText(text).build();
const future = searchManager.suggest(query);
futureRef.current = future;

future.onComplete(
result => {
if (futureRef.current !== future) {
return;
}

futureRef.current = null;
setSuggests(result.suggests);
future.destroy();
},
error => {
if (futureRef.current !== future) {
return;
}

futureRef.current = null;
console.warn(error);
future.destroy();
},
);
};

return (
<View>
<TextInput onChangeText={onChangeText} />
<FlatList
data={suggests}
keyExtractor={(item, index) => `${item.title.text}-${index}`}
renderItem={({ item }) => <Text>{item.title.text}</Text>}
/>
</View>
);
}