普段Navigation関係はReact-Navigationを利用していて、React-NavigationにもModalを出す機能はあるが、StackNavigationを入れ子にする必要がある等、ちょっと癖があるので、react-native-modalを試してみます。
やりたいこと
下記のようなモーダルを出す。
準備
npm install --save react-native-modal
実装
これで動く。
基本的に<Modal></Modal>でコンテンツを囲ってやればいい。
App.js
import React from 'react';
import { StyleSheet, Text, View, SafeAreaView, Button } from 'react-native';
import Modal from "react-native-modal";
export default class App extends React.Component {
state = {
isModalVisible: false
}
toggleModal = () => {
this.setState({ isModalVisible: !this.state.isModalVisible });
}
render() {
return (
<SafeAreaView style={{ flex: 1 }}>
<Text>App</Text>
<Button
title="Show modal"
onPress={this.toggleModal}
/>
<Modal isVisible={this.state.isModalVisible}>
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: "#fff" }}>
<Text>Modal Content</Text>
<Button
title="Close modal"
onPress={this.toggleModal}
/>
</View>
</Modal>
</SafeAreaView>
);
}
}
応用(コンテンツの外だし)
Modalで表示する内容が複雑になってくると、メイン?コンテンツの中に定義するのはうざい。
Modalで表示する内容を外部ファイルにしてみる。
Child.js
基本的には<View></View>部分を切り出しただけだが、モーダルを閉じるためのメソッドをprops経由で受けとっている。
Child.js
import React from 'react';
import { StyleSheet, Text, View, SafeAreaView, Button } from 'react-native';
export default class Child extends React.Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: "#fff" }}>
<Text>Modal Content</Text>
<Button
title="Close modal"
// イベントをpropsでもらう
onPress={this.props.nav.toggleModal}
/>
</View>
);
}
}
App.js
Child.jsを読み込み、this全体をnavという名前でpropsで渡している。
App.js
import React from 'react';
import { StyleSheet, Text, View, SafeAreaView, Button } from 'react-native';
import Modal from "react-native-modal";
import Child from './Child';
export default class App extends React.Component {
state = {
isModalVisible: false
}
toggleModal = () => {
this.setState({ isModalVisible: !this.state.isModalVisible });
}
render() {
return (
<SafeAreaView style={{ flex: 1 }}>
<Text>App</Text>
<Button
title="Show modal"
onPress={this.toggleModal}
/>
<Modal isVisible={this.state.isModalVisible}>
<Child nav={this} />
</Modal>
</SafeAreaView>
);
}
}
モーダルの大きさ
もちろん、モーダル自体の大きさもstyleで調整可能。
App.js
import React from 'react';
import { StyleSheet, Text, View, SafeAreaView, Button } from 'react-native';
export default class Child extends React.Component {
render() {
return (
<View style={{ justifyContent: 'center', alignItems: 'center', backgroundColor: "#fff", height:300 }}>
<Text>Modal Content</Text>
<Button
title="Close modal"
// イベントをpropsでもらう
onPress={this.props.nav.toggleModal}
/>
</View>
);
}
}