背景が見えるモーダル画面って個人的には好きです。
今回はその作成方法を紹介します。
使用ライブラリ
@react-navigation/stack
@react-navigation/native
react-native-safe-area-context
react-native-linear-gradient
styled-components
透過するモーダルページ(外枠)の作成
const TransparentModalPage: React.FunctionComponent = ({ children }) => {
const navigation = useNavigation();
return (
<LinearGradient
colors={['rgba(0,0,0,0)', 'rgba(0,0,0,0.9)']}
style={{ flex: 1 }}
>
<TouchableWithoutFeedback
style={{ flex: 1, alignSelf: 'stretch' }}
onPress={() => navigation.goBack()}
>
<View style={{ flex: 1 }} />
</TouchableWithoutFeedback>
<View style={{ justifyContent: 'center' }}>{children}</View>
</LinearGradient>
);
};
ToucableWithoutFeedback
の部分で、子要素のモーダルコンテンツ(children
)以外をタップした場合に、ページを閉じるように設定しています。
モーダルのコンテンツを作成
const RoundView = styled(View)`
border-top-left-radius: 10px;
border-top-right-radius: 10px;
background-color: 'rgba(255,255,255,1)';
`;
export const ModalCard: React.FunctionComponent = ({ children }) => {
return (
<RoundView>
<View style={{ paddingVertical: 16 }}>
<View
style={{
alignSelf: 'center',
width: 50,
borderBottomWidth: 3,
borderBottomColor: 'rgba(0,0,0,1)',
borderRadius: 8,
}}
/>
</View>
<View style={{ paddingHorizontal: 32, paddingBottom: 32 }}>
{children}
</View>
{/* To avoid a typescript error. */}
<SafeAreaView>
<></>
</SafeAreaView>
</RoundView>
);
};
SafeAreaView
は、モーダル部分が下に詰めすぎないように制御しています。
画面コンポーネントの作成
const ModalScreen = () => (
<TransparentModalPage>
<ModalCard>
<View
style={{ height: 50, alignItems: 'center', justifyContent: 'center' }}
>
<Text>Modal Area</Text>
</View>
</ModalCard>
</TransparentModalPage>
);
作成したTransparentModalPage
, ModalCard
に子要素を設定するだけ完了です。
ナビゲーター・スクリーンの作成
const Stack = createStackNavigator();
const StackNavigator = () => {
return (
<Stack.Navigator mode="modal" headerMode="screen">
...
<Stack.Screen
name="ModalScreen"
component={ModalScreen}
options={{
headerShown: false,
cardStyle: { backgroundColor: 'transparent', opacity: 1 },
}}
/>
</Stack.Navigator>
);
};
ModalScreen
の画面オプションは、cardStyle
で背景を透明設定にします。
この設定がないと、モーダル画面にグラデーションはかかりますが、背景が表示されません。
以上で設定は完了です。
おわりに
ここでは紹介しませんでしたが、 Animation や GestureHandler を用いると、より「アプリらしい」挙動をさせることができます。
組み合わせ次第で、いろんなモーダル画面が作れるので、ぜひ試してみてください。