React Native의 하단 탭 네비게이터에서 전체 화면 누를 수 있는 오버레이 만들기

13353 단어 reactreactnative
지난 주에 React Native 문제를 접했는데, Android에서 z-index 포지셔닝과 관련이 있다고 생각했기 때문에 처음에는 다소 혼란스러웠습니다. Android에서 자식 구성 요소가 렌더링되는 방식Pressable과 관련하여 구체적으로 확인된 RN 문제가 있는 것으로 나타났습니다. 자세한 내용이 궁금하시면 this page의 맨 아래로 스크롤하십시오.

특정 사용 사례에 대한 더 많은 컨텍스트를 제공하기 위해 몇 가지 다이어그램에서 직접 시도하기로 결정했습니다. 최고는 아니지만 잘만되면 작업을 수행합니다. 😛 iPad에서 손으로 그린 ​​다이어그램을 Mac 노트북으로 내보내는 방법에 대한 팁이 있는 사람이 있으면 알려주십시오.

문제



모바일 화면을 그려보세요. 화면 하단에 React Navigation bottom tab navigator 이 있습니다.



내가 원했던 것은 눌렀을 때 사라지는 전체 화면, 즉 Pressable 오버레이에 더 어두운 오버레이가 나타나는 것이었습니다. 다른 부작용 때문에 오버레이 표시/숨기기 트리거는 탭 탐색기에서 수행해야 했습니다.



이를 위해 <Tab.Screen> options 소품을 사용하여 사용자 지정 tabBarIcon 을 전달했습니다. 여기에는 탭 아이콘뿐만 아니라 다음과 같은 조건부Pressable 오버레이도 포함됩니다... ( useWindowDimensionsreact-native 후크를 사용하여 전체 화면을 표시하도록 오버레이의 높이와 너비를 설정했습니다.

export default function TabNavigator() {
  const windowDimensions = useWindowDimensions()
  const [showOverlay, setShowOverlay] = React.useState < boolean > false

  const tabScreenOptions = {
    // other options
    tabBarIcon: ({ focused, color }: { focused: boolean, color: string }) => {
      return (
        <>
          // tab icon component
          {showOverlay ? (
            <Pressable
              onPress={closeOverlay}
              style={[styles.overlay, { height: windowDimensions.height, width: windowDimensions.width }]}
            />
          ) : null}
        </>
      )
    },
  }

  return (
    <Tab.Navigator>
      // Other tab screens
      <Tab.Screen component={TabScreen} name="Tab name" options={tabScreenOptions} />
    </Tab.Navigator>
  )
}

const styles = StyleSheet.create({
  overlay: {
    backgroundColor: 'black',
    flex: 1,
    opacity: 0.5,
    position: 'absolute',
    zIndex: 1,
  },
})


iOS에서 테스트할 때 모두 예상대로 작동합니다. showOverlay 상태 변수가 true 로 설정되면 전체 화면 오버레이가 나타나고 누를 수 있습니다. 🎉



그러나 Android는 자식(즉, 오버레이)과 부모(탭 내비게이터)의 겹치는 영역만 누를 수 있도록 허용하기 때문에 예상대로 작동하지 않습니다. 제 경우에는 탭 네비게이터가 전체 화면 오버레이보다 작기 때문에 막혔습니다. iOS에서 볼 수 있는 동작을 모방하려면 탭 탐색기 높이와 너비를 전체 화면의 높이와 너비로 만들어야 합니다. 제 경우에는 실행 가능한 옵션이 아닙니다.



잠재적 솔루션



그래서 내가 무엇을 했습니까? 나는 React context 을 사용하여 더 많은 유연성을 얻기 위해 약간 복잡한 길을 가기로 결정했습니다. 탭 내비게이터는 모든 화면과 화면 내에 있는 하위 구성 요소의 부모 역할을 하므로 탭 내비게이터 수준에서 컨텍스트 공급자를 설정한 다음 계층 구조 아래에 필요한 구성 요소에 컨텍스트 소비자를 배치할 수 있습니다.

export function TabNavigator() {
  const [showOverlay, setShowOverlay] = React.useState < boolean > false
  export const OverlayContext = React.createContext({ closeOverlay: () => {}, showOverlay: false })

  // const tabScreenOptions same as before

  const overlayContext = {
    closeOverlay,
    showOverlay,
  }

  const closeOverlay = React.useCallback(async () => {
    setShowOverlay(false)
    // do some other things
  }, [])

  return (
    <OverlayContext.Provider value={overlayContext}>
      <Tab.Navigator>
        // Other tab screens
        <Tab.Screen component={TabScreen} name="Tab name" options={tabScreenOptions} />
      </Tab.Navigator>
    </OverlayContext.Provider>
  )
}


소비자를 설정하기 위해 TabNavigator 의 자식 구성 요소에서 useContext 후크를 사용했습니다.

export function ChildComponent() {
  const overlayContext = React.useContext(OverlayContext)

  return (
    <>
      {Platform.OS === 'android' && overlayContext.showOverlay ? (
        <Pressable
          onPress={overlayContext.closeOverlay}
          style={[styles.overlay, { height: windowDimensions.height, width: windowDimensions.width }]}
        />
      ) : null}
      // the child component
    </>
  )
}


구체적으로 말하자면 Platformreact-native 모듈을 사용하여 이것이 Android 운영 체제에서만 표시되는지 확인했습니다. styles.overlay 스타일링은 이전에 했던 것과 동일합니다.

당신이 무슨 생각을하는지 제게 알려주세요! 나는 https://bionicjulia.com에 블로그를 작성했으며 및에서 찾을 수 있습니다.

좋은 웹페이지 즐겨찾기