简体   繁体   English

使用带有 React-Native 的 zIndex 样式将视图置于 Modal 之上

[英]Bring View on top of Modal using zIndex style with React-Native

zIndex has been introduced recently to React-Native to change the position of a View in the stack of layers.最近在 React-Native 中引入了zIndex来改变View在层堆栈中的位置。

Although, I'm not able to bring a View on top of a Modal component.虽然,我无法在Modal组件之上添加View

My code looks like this:我的代码如下所示:

render() {
  return (
    <View>
      <Modal visible>
        {props.children}
      </Modal>
      <View style={{ zIndex: 1000 }}>
        <Text>Loading...</Text>
      </View>
    </View>
  );
}

I guess I could stop using <Modal> and create a regular animated <View> that would behave like the Modal , but I'd rather find another solution.我想我可以停止使用<Modal>并创建一个常规动画<View> ,它的行为类似于Modal ,但我宁愿找到另一个解决方案。

Any idea?任何的想法?

No amount of zIndex manipulation will bring something above a react-native Modal , unfortunately.不幸的是,再多的zIndex操作都不会带来高于 react-native Modal东西。 The Modal component is a native view that sits on top of the rest of your react-native application. Modal组件是一个本机视图,它位于您的本机应用程序的其余部分之上。 The only way to put something above it is to put something in the modal itself, or alternately to use a js only implementation of a Modal.将一些东西放在它上面的唯一方法是在模态本身中放置一些东西,或者交替使用仅 js 实现的模态。

Incidentally, the react-native-community version of modal is also built on the react-native modal, so would have the same issue.顺便说一句,反应原生社区版本的 modal 也是建立在反应原生模式上的,所以会有同样的问题。 There's a discussion about different js implementation here: https://github.com/react-native-community/react-native-modal/issues/145这里有关于不同 js 实现的讨论: https : //github.com/react-native-community/react-native-modal/issues/145

Not possible with modal.模态不可能。 As the modal should always shown regardless of whatever the zIndex is given to it and other components in the screen因为无论给它什么 zIndex 和屏幕中的其他组件,模态都应该始终显示

It will always shown you unless you make visible=false除非您使可见=假,否则它将始终向您显示

To implement what you want.实现你想要的。 You could use a absolutely positioned view with some zIndex trick to move this view back and front.您可以使用带有一些 zIndex 技巧的绝对定位视图来前后移动此视图。

render() {
  return (
    <View>
       <View style={{position:'absolute',top:0,bottom:0,left:0,right:0,zIndex:visible?-1:2}}>
          {props.children}
       </View>
       <View style={{ zIndex: 1 }}>
          <Text>Loading...</Text>
       </View>
     </View>
  );
}

I was struggling with the same problem and finally, I solved it.我一直在努力解决同样的问题,最后,我解决了它。 here's what I found:这是我发现的:

First, the problem: the problem is the modal appears on top of all screen layers which means it will show on all app elements, so if you open two modals at the same time the app will make it all on each other cuz the app don't know what the modals order it should be, for that reason, you see your modal behind the other one.首先,问题:问题是模态出现在所有屏幕层的顶部,这意味着它将显示在所有应用程序元素上,因此如果您同时打开两个模态,应用程序将使其全部出现在彼此上,因为应用程序不不知道模态顺序应该是什么,因此,您会看到您的模态在另一个之后。

Second, the solution: to make the second modal opens on the first modal you need to arrange the order of the modals opening, which means you open the parent modal then open the child modal.二、解决办法:要让第二个modal在第一个modal上打开,需要安排modals的打开顺序,也就是先打开父modal,再打开子modal。 and for doing that I'm using promise which allow me to do that like this steps example:-为此,我使用了 promise,它允许我像以下步骤示例一样执行此操作:-

1 - create promise 1 - 创建承诺

const [isOpen, setOpen] = useState({ backDrop: false, modal: false }); // modals open state

function openDialog() {
    return new Promise((resolve) => {
        setOpen((previous) => ({ ...previous, backDrop: props.isOpen }))
        resolve()
    })
}

2 - I use useEffect() to trigger modal opening props and then invoke an async function which will await the openDialog() function at the first step above and then will set open state after the first function invoked. 2 - 我使用useEffect()来触发模式打开道具,然后调用一个异步函数,该函数将在上面的openDialog()等待openDialog()函数,然后在调用第一个函数后设置打开状态。

useEffect(() => {
    (async function () {
        await openDialog()
        setOpen((previous) => ({ ...previous, modal: props.isOpen }))
    }())
}, [props.isOpen])

this how you can control opening the modals pre-arranged and on top of each other这是您如何控制打开预先安排的和彼此重叠的模态

 const styles = StyleSheet.create({ modal: { backgroundColor: 'white', margin: 0, // This is the important style you need to set alignItems: undefined, justifyContent: undefined, } <Modal isVisible={true} style={styles.modal}> <View style={{ flex: 1 }}> <Text>Hello!</Text> </View> </Modal>

You have to change the z-index of the modal not the one of the view (and a z-index of value 1 would suffice):您必须更改模式的 z-index 而不是视图的 z-index(值1的 z-index 就足够了):

render() {
  return (
    <View>
      <Modal visible style={{ zIndex: 1 }}>
        {props.children}
      </Modal>
      <View>
        <Text>Loading...</Text>
      </View>
    </View>
  );
}

An element with a larger z-index generally covers an element with a lower one ( MDN docs ).具有较大 z-index 的元素通常会覆盖具有较低 z-index 的元素( MDN 文档)。

EDIT:编辑:

Another solution is to change the order of the elements:另一种解决方案是更改元素的顺序:

render() {
  return (
    <View>
      <View>
        <Text>Loading...</Text>
      </View>
      <Modal visible>
        {props.children}
      </Modal>
    </View>
  );
}

With this solution you don't need z-index because the modal is already on top of the view.使用此解决方案,您不需要z-index因为模式已经在视图的顶部。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM