React Native/Expo:当“visible”属性在 iOS 上为 true 时,模态不显示

Jon*_*ell 6 ios react-native expo

我有一个在 React Native 中构建的应用程序,其中有一个模式,当按下按钮时会出现该模式并提示用户输入。我在应用程序中制作了其他模态,使用我现在使用的相同方法可以正常工作。但是,当我更改此模式的状态(确定模式是否可见)时,它似乎完全忽略它并且不显示。该模式适用于我的 Android 和我的许多 Android 模拟器,但由于某种原因它不适用于我的 iphone 10。

我有一个文件 GameScreen.js,它是屏幕组件,并在其中保存模式。它还保存模式可见性的相关方法和状态:

import { 
    Body, 
    Button, 
    Container, 
    Content, 
    Header, 
    Icon, 
    Left,  
    Right,  
    View } from 'native-base';
import { BackHandler, StyleSheet, Text, TextInput, TouchableOpacity, Platform } from 'react-native';
import React, { Component, createRef } from 'react';

import myModal from '../components/myModal';

export default class GameScreen extends Component {
  constructor(props) {
    super(props)

    this.state = { 
      // other state
      isVisible: false,
    }
    this.displayModal = this.displayModal.bind(this);
  }

  displayModal(show) {
    this.setState({
      isVisible: show
    })
  }

  render() {
    return (
      <Container>
        <myModal
        displayModal={this.displayModal}
        isVisible={this.state.isVisible}
        />

        <View>
          <TouchableOpacity
          style={styles.button}
          onPress{() => this.displayModal(true)} >
            <Image />
          </TouchableOpacity>
        </View>
      </Container>
    )
  }
}
Run Code Online (Sandbox Code Playgroud)

我的模式在它自己的文件中,它看起来像这样(myModal.js):

import { 
    Button, 
    Card, 
    CardItem, 
    Container, 
    Text, 
    View } from 'native-base';
import { Modal, StyleSheet } from 'react-native';
import React, { Component } from 'react';

export default class myModal extends Component {

    render() {
            return (
                <Container>
                    <Modal
                    transparent 
                    animationType='fade'
                    visible={this.props.isVisible} 
                    onRequestClose={() => this.props.displayModal(false)} 
                    >
                        <View>
                           // My view stuff
                        </View>
                    </Modal>
                </Container>
            )
     }
}
Run Code Online (Sandbox Code Playgroud)

我尝试将控制台日志放入模式文件中,以查看状态是否确实在变化,而且看起来确实如此。我在 render() 和 componentDidUpdate() 中添加了 isVisible 状态的日志,一旦我按下 GameScreen 中的按钮,它总是会输出 true,但似乎模式会忽略它。当我手动将 'visible' 属性更改为 true 时,它​​显示得很好,所以它不像我想要渲染的内容有问题。

我还尝试在生产模式下运行博览会,因为有些人提到了开发模式和反应本机模式的问题。我按照 expo 文档的建议使用“expo start --no-dev --minify”启动了 Metro 捆绑程序,但问题仍然存在。

正如我上面所说,这种方法在应用程序的其他部分运行良好,但由于某种原因似乎不喜欢 GameScreen。而且,这个问题只发生在 iOS 上。我没有任何其他 iphone,也无法访问 mac 的 xCode,所以我猜这可能是手机本身的问题,但它可以很好地呈现我应用程序上的其他模式。一段时间以来,我一直在敲键盘试图解决这个奇怪的错误,所以感谢您的回复!

Jon*_*ell 17

所以我现在才想出来,这是一个愚蠢的解决方案,我希望对其他人有所帮助。谢谢@Kamal Hossain,你的建议帮助我诊断了问题。

因此,在我的 GameScreen 中,我使用了一个名为“react-native-actions-sheet”的 API,这是一个漂亮的小抽屉式 UI 组件,其中包含试图打开模式的按钮。按下按钮后抽屉也会关闭。该按钮与状态交互得很好,但我认为关闭抽屉的过程在某种程度上扰乱了模式渲染。

我的工作解决方案是让按钮等待几分之一秒,然后再尝试在 ios 上打开模式,现在效果很好:

<TouchableOpacity
  onPress={() => {
    // closes drawer
    this.props.toggleActionSheetVisibility();
    // waits if on ios and then opens modal
    setTimeout(() => this.displayModal(true), Platform.OS === "ios" ? 200 : 0); 
  }}
/>
Run Code Online (Sandbox Code Playgroud)

我不知道为什么它只发生在 ios 上,但我希望这对将来的人有帮助。

  • 除了超时之外,您还可以尝试 https://reactnative.dev/docs/interactionmanager InteractionManager.runAfterInteractions(() =&gt; { return this.displayModal(true) }) (3认同)