volga-volga / react-native-yamap

React Native Yandex Maps | Яндекс Карты | Yandex.MapKit implementation for react native | YandexMaps
151 stars 84 forks source link

Карта выходит за границы экрана (ios only) #97

Closed byazamat closed 2 years ago

byazamat commented 2 years ago

Здравствуйте, обнаружил не понятный баг с YaMap на IOS.

Подробнее о баге: При первом открытии карты (То есть после первой инициализации: YaMap.init("@API_KEY")) карта открывается в нормальном виде:

photo_2022-03-17_06-59-40

Но уже при следующем входе в карту, она выходит за границы экрана (обратите внимание на логотип Яндекс):

photo_2022-03-17_06-59-43

Пожалуйста объясните мне как мне решить эту проблему.

Система: macOS: Monterey (12.1) M1 device: iPhone XR react-native: 0.67.3 react-native-yamap: 4.0.3

labtorie commented 2 years ago

Тоже столкнулся с этой проблемой. В качестве костыля можно рендерить карту по таймауту, то есть немного позже, чем отрисуется View, внутри которой карта находится

byazamat commented 2 years ago

@labtorie Спасибо, это действительно помогло!

Если кто-то столкнулся с такой же проблемой и не знает как решить ее то сделайте так:

  1. Создайте const [destroyMap, setDestroyMap] = useState(true);

  2. В методе useEffect создайте слушатель событий на фокус скрина, обязательно удалите слушатель при выходе из скрина:

    useEffect(() => {
    navigation.addListener('focus', e => {
      setDestroyMap(false);
    });
    return () =>
      navigation.removeListener('focus', e => {
        setDestroyMap(false);
      })
    }, [navigation]);
  3. И в самом рендере сделайте проверку:

    return (
    <View style={styles.container}>
        {destroyMap === false && <YaMap ... />}
        ...
    </View>
    )

Кстати, так же имеется такой баг с картами, наблюдал это поведение не только с Yamap, это то что при каждом выходе из скрина, на устройстве не освобождается ОЗУ. Это значит что если зайти и выйти в скрин карты раз 10 то это займет все ОЗУ, что приведет к вылету приложения. Что бы решить эту проблему мы прибегнем к методу описанному выше, логика почти такая же. Только в это случае мы должны перед выходом из скрина удалить карту. В итоге это будет выглядеть как-то так:

import React, {useState, useEffect} from 'react';
import {View} from 'react-native';
import YaMap from 'react-native-yamap';

const MapScreen = () => {
  const [destroyMap, setDestroyMap] = useState(true);

  useEffect(() => {
    navigation.addListener('focus', e => {
      setDestroyMap(false);
    });
    navigation.addListener('beforeRemove', e => {
      e.preventDefault();
      setDestroyMap(true);
      navigation.dispatch(e.data.action);
      return;
    });
    return () => {
      navigation.removeListener('focus', e => {
        setDestroyMap(false);
      })
      navigation.removeListener('beforeRemove', e => {
        console.log('unmount');
        e.preventDefault();
        setDestroyMap(true);
        navigation.dispatch(e.data.action);
        return;
      });
    }
  }, [navigation]);

  return (
    <View style={styles.container}>
      <StatusBarFocus translucent barStyle="dark-content" />
      {destroyMap === false && <YaMap/>}
    </View>
  )
}

Если будут вопросы пишите 😁

Wimmind commented 2 years ago

@byazamat вопрос не по теме, но как ты установил рус язык?) YaMap.init('key'); YaMap.setLocale('ru').catch(e => console.error(e)) инициализирую это в index.js перед компонентом, который регистрирую, но локаль не работает, также карта при зуме не показывает регионы/улицы/номера домов что может быть не так?

pioner92 commented 2 years ago

fixed