最初からプルタブが露出しているタイプのモーダルが作りたかったので、ライブラリを使って作ってみました。
完成はこんな感じ
#ライブラリを使用
Reanimated Bottom Sheetというライブラリを使用します。リファレンスはこちら
ライブラリのインストール
npm install reanimated-bottom-sheet react-native-gesture-handler react-native-reanimated
リファレンスのサンプルコードから引っ張ってきたものを以下で改良していきます。
#プルタブの作成
App.js
import * as React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import BottomSheet from 'reanimated-bottom-sheet';
export default function App() {
const renderContent = () => (
<View style={styles.modalWrapper}>
<View style={styles.modalHeader}>
<View style={styles.modalPulltab}/>
</View>
<View style={styles.modalContents}>
<View style={{height: '100%'}}>
<Text>modal contents here</Text>
</View>
</View>
</View>
);
const sheetRef = React.useRef(null);
return (
<>
<View
style={{
flex: 1,
backgroundColor: 'papayawhip',
alignItems: 'center',
justifyContent: 'center',
}}
>
<Button
title="Open Bottom Sheet"
onPress={() => sheetRef.current.snapTo(0)}
/>
</View>
<BottomSheet
ref={sheetRef}
snapPoints={['90%', '50%', 50]}
initialSnap={2} // モーダルの初期位置を決める。snapPointsのインデックス番号を指定
borderRadius={20}
renderContent={renderContent}
/>
</>
);
}
const styles = StyleSheet.create({
modalWrapper: {
backgroundColor: 'rgba(221,221,221,0.3)',
},
modalHeader: {
backgroundColor: 'rgba(153,153,153,0.7)',
height: 50, // 引っ張り出す部分を露出させたいので、初期位置のsnapPointsと同じ高さを指定する
alignItems: 'center',
justifyContent: 'center'
},
modalPulltab: {
backgroundColor: 'gray',
height: 5,
width: 40,
},
modalContents: {
backgroundColor: 'rgba(230,230,255,0.8)',
paddingLeft: 16,
paddingRight: 16,
flexGrow: 1
}
})
BottomSheet
のsnapPoints
というプロパティはモーダルが固定される位置を指定できます。また、initialSnap
で初期状態でのsnapPoints
を指定できるため、今回は50
を指定してモーダルの上部50を露出させています。