ボタンでネイティブのモーダルを反応させる方法


私は最近、反応ネイティブと一緒に働いてきたし、私は基本的なコンポーネントに追加するために必要ないくつかの未実装の機能に遭遇した.それらのコンポーネントのうちの1つは、別の上のビューを示すのに使用される反応するネイティブのモーダルコンポーネントです.それはそれより多くの機能を約束しません、しかし、それはあなた自身のポップアップを実装するのに非常に役に立つことがありえます.
一方、単純なモードであるので、それはあなたがXのようなポップアップコンポーネントのために期待するすべてを含んでいません.あなたがモーダルコンポーネントから始めているとき、それらの2つの特徴を加える方法をあなたを歩いています.
急いでいるならば、あなたは私のgithubに最終結果を見つけることもできます:https://github.com/CindyPotvin/react-native-popup

モーダルを閉じる方法


基本的なアプリから始めましょう.ポップアップを示すJS.私はまた、ポップアップが表示されるように影を持っているいくつかのスタイルを追加し、マージンの寛大な量ので、我々は後でそれを横にクリックしてポップアップをテストすることができます.

import React, { useState } from 'react';
import { StyleSheet, Modal, Text, View } from 'react-native';

export default function App() {
  const [modalVisible, setModalVisible] = useState(true);

  return (
    <View style={styles.container}>
      <Text>Open up App.js to start working on your app!</text>
      <Modal visible={modalVisible}>
        <View style={styles.modal}>
          <Text>
            Popup content.
          </Text>
        </View>
      </Modal>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "white",
    alignItems: "center",
    justifyContent: "center",
  },
  modal: {
    flex: 1,
    margin: 50,
    padding: 5,
    backgroundColor: "white",
    shadowColor: "black",
    shadowOffset: {
      width: 0,
      height: 2,
    },
    shadowOpacity: 0.25,
    shadowRadius: 4,
    elevation: 5,
  },
});

モーダルは目に見えるプロップに従って表示される.今、状態の値は常にtrueですので、ポップアップは常に表示されます.
ボタンや他の方法で状態を変更することができなくても、モーダルはバックボタンでAndroid上で閉じることができます(Apple TVのメニューボタンはドキュメントに従って同じ効果を持つべきですが、私はテストする必要はありません).
ボタンを押すと、モードのOnRequestCloseプロップで指定された関数が呼び出されます.このため、アプリケーションのメイン画面が表示されます.

<Modal
  visible={modalVisible}
  onRequestClose={() => setModalVisible(false)}>

閉じたボタンを反応ネイティブモードに加える方法


まず、ボタン自体を追加しなければなりません.その場合、私はポップアップの右上隅に小さなXを加えたかったです.
位置決め作業をどのようにすればよいのでしょうか
  • 右上隅に絶対にボタンを配置します.その後、コンテンツの残りの部分に何かを行うことができますが、その後、それは通常のレイアウトの流れのうち、Xをオーバーラップするコンテンツを持つリスクを実行します.あなたが同時にボタンの下と下のスペースを使用する場合は、それは私たちに第二のオプションにつながるかなり不可能です.
  • ボタンをFlexboxで配置し、ヘッダーのボタンの左側にスペースを残します.その後、ヘッダーと下部のコンテンツを別々に埋めることができます.あなたがポップアップであるはずである何かをしているならば、タイトルを持つことはかなり標準的な特徴でもあります.
  • ここでは、コンポーネントが現在のXで追加されたものです.
    
    import React, { useState } from 'react';
    import { StyleSheet, Modal, Text, View, TouchableOpacity } from 'react-native';
    
    export default function App() {
      const [modalVisible, setModalVisible] = useState(true);
    
      return (
        <View style={styles.container}>
          <Text>Open up App.js to start working on your app!</Text>
          <Modal visible={modalVisible} 
                 onRequestClose={() => setModalVisible(false)}>
            <View style={styles.modal}>
              <View style={styles.modalHeader}>
                <View style={styles.modalHeaderContent}>
                   <Text>Other header content</Text></View>
                   <TouchableOpacity>
                     <Text 
                        style={styles.modalHeaderCloseText}>X</Text>   
                   </TouchableOpacity>
              </View>
              <View style={styles.modalContent}>
                <Text>
                  Popup content.
                </Text>
              </View>
            </View>
          </Modal>
        </View>
      );
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        backgroundColor: "white",
        alignItems: "center",
        justifyContent: "center",
      },
      modal: {
        flex: 1,
        margin: 50,
        padding: 5,
        backgroundColor: "white",
        shadowColor: "black",
        shadowOffset: {
          width: 0,
          height: 2,
        },
        shadowOpacity: 0.25,
        shadowRadius: 4,
        elevation: 5,
      },
      /* The content of the modal takes all the vertical space not 
         used by the header. */
      modalContent: {
        flex: 1
      },
      modalHeader: {
        flexDirection: "row",
      },
      /* The header takes up all the vertical space not used by the 
         close button. */
      modalHeaderContent: {
        flexGrow: 1,
      },
      modalHeaderCloseText: {
        textAlign: "center",
        paddingLeft: 5,
        paddingRight: 5
      }
    });
    
    
    ヘッダーは、行として表示されるフレックスコンテナーですflexGrow:1 すべての残りのスペースを取る必要があることを示します.
    ポップアップの内容の残りはflex:1 ので、すべての残りの高さを取るアイテム.
    この時点で残っている唯一のことは、ボタンを配線することです.
    
    <TouchableOpacity onPress={() => setModalVisible(false)}>
      <Text style={styles.modalHeaderCloseText}>X</Text>
    </TouchableOpacity>       
    
    

    外側をクリックすることによってモーダルを閉じる方法


    また、外部をタップしてモードを閉じるには、我々はそれらのタップをキャッチするために追加のコンポーネントが必要です.
    一方、このコンポーネントで子コンポーネントのタップをキャッチする必要はありません.ポップアップ自体をクリックして閉じる必要はありません.調べることでevent.target == event.currentTarget , 選択された項目がコンポーネント自体であり、子プロセスの一つではないことを確認します.
    Touchleleopacityが付属しているポップアップの外側に触れるとき、私は「調光」効果をタップしたくなかったので、私はプレス可能なコンポーネントを使いました.この新しいプレス可能なコンポーネントは、モードで以前定義したすべてのコンポーネントをラップします.
    ヘッダーとポップアップ内容がどこにあるかを示すいくつかの余分の境界線で、完成したポップアップは、ここにあります:
    
    import React, { useState } from 'react';
    import { StyleSheet, Modal, Text, View, Pressable, TouchableOpacity } from 'react-native';
    
    export default function App() {
      const [modalVisible, setModalVisible] = useState(true);
      return (
        <View style={styles.container}>
          <Text>Open up App.js to start working on your app!</Text>
          <Modal
            visible={modalVisible}
            onRequestClose={() => setModalVisible(false)}>
            <Pressable style={styles.outsideModal}
              onPress={(event) => { 
                if (event.target == event.currentTarget) { 
                   setModalVisible(false); } }} >
              <View style={styles.modal}>
                <View style={styles.modalHeader}>
                  <View style={styles.modalHeaderContent}>
                     <Text>Other header content</Text>
                  </View>
                  <TouchableOpacity 
                     onPress={() => setModalVisible(false)}>
                    <Text style={styles.modalHeaderCloseText}>X</Text>
                  </TouchableOpacity>
                </View>
                <View style={styles.modalContent}>
                  <Text>
                    Popup content.
                  </Text>
                </View>
              </View>
            </Pressable>
          </Modal>
        </View>
      );
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        backgroundColor: "white",
        alignItems: "center",
        justifyContent: "center",
      },
      modal: {
        flex: 1,
        margin: 50,
        padding: 5,
        backgroundColor: "white",
        shadowColor: "black",
        shadowOffset: {
          width: 0,
          height: 2,
        },
        shadowOpacity: 0.25,
        shadowRadius: 4,
        elevation: 5,
      },
      /* The content of the modal takes all the vertical space not 
         used by the header. */
      modalContent: {
        flex: 1,
        borderWidth: 1,
        borderColor: "black"
      },
      modalHeader: {
        flexDirection: "row",
        borderWidth: 1,
        borderColor: "black"
      },
      /* The header takes up all the vertical space not used by the 
         close button. */
      modalHeaderContent: {
        flexGrow: 1,
      },
      modalHeaderCloseText: {
        textAlign: "center",
        paddingLeft: 5,
        paddingRight: 5
      },
      outsideModal: {
        backgroundColor: "rgba(1, 1, 1, 0.2)",
        flex: 1,
      }
    });
    
    
    これには小さな制限があることに注意してください:pressleopacacityのための背景色は透明または半透明の値に設定することはできませんので、ポップアップの下にコンテンツが表示されなくなります.
    次のステップでは、モードコンポーネントとその内容をパッケージ内の任意のヘッダーまたはコンテンツを挿入できるように、アプリケーションで再利用することができる新しいコンポーネントにパッケージ化するには、次の手順は、これは現在の記事の範囲外です.
    最後のバージョンを自分で実行してみてみてください.https://github.com/CindyPotvin/react-native-popup そして、ここのエキスポの軽食として:https://snack.expo.dev/@cindyptn/react-native-popup-with-x-button