This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.
モーダルを作成する
ページを編集
このチュートリアルでは、Expo UI の BottomSheet コンポーネントで絵文字ピッカーを作成し、選択した絵文字を React Native アプリにステッカーとして表示する方法を学びます。
モーダルは、アプリの他のコンテンツの上にコンテンツを表示します。一般的に、モーダルはユーザーの注意を重要な情報に向けたり、アクションを促したりするために使用されます。ボトムシートは、画面下からスライドして表示されるモーダルの一種です。
この章では、Expo UI の BottomSheet コンポーネントを使って絵文字ピッカーを作成します。Android と iOS では、プラットフォームのネイティブのボトムシートを表示します。web では、ページ下部にシートを表示します。

React Native の Modal API を使ってモーダルコンポーネントを構築し、絵文字ピッカーを表示してユーザー操作を処理します。
1
ボタンを表示するための状態変数を宣言する
ボトムシートを実装する前に、新しいボタンを 3 つ追加します。これらのボタンは、ユーザーがメディアライブラリから画像を選択したり、プレースホルダー画像を使ったりした後に表示されます。ボタンのうちの 1 つが絵文字ピッカーを開きます。
src/app/(tabs)/index.tsx で:
- 絵文字ピッカーを開くボタンや他のオプションの表示・非表示を切り替えるために、ブール値の状態変数
showAppOptionsを宣言します。アプリ画面の読み込み時にはfalseにして、画像を選択する前にはオプションを表示しないようにします。ユーザーが画像を選択したり、プレースホルダー画像を使ったりすると、trueに設定します。 pickImageAsync()関数を更新して、ユーザーが画像を選択した後にshowAppOptionsの値をtrueに設定します。- テーマが設定されていないボタンの
onPressプロパティで、alert()をshowAppOptionsをtrueに設定する関数に置き換えます。
上記のスニペットでは、showAppOptions の値に応じて Button コンポーネントをレンダリングし、ボタンを三項演算子ブロックの中に移動しています。showAppOptions の値が true の場合は、空の <View> コンポーネントをレンダリングします。この状態については次のステップで対応します。
2
ボタンを追加する
この章で実装するオプションボタンのレイアウトを分解してみましょう。デザインは次のようになっています。
親の <View> の中に、横一列に並んだ 3 つのボタンが含まれています。中央のプラスアイコン (+) のボタンは絵文字ピッカーを開くもので、他の 2 つとは異なるスタイルになっています。
第 3 章 の Button コンポーネントと同様に、オプションボタンは Android と iOS では Expo UI を、web では React Native のコンポーネントを使用します。各ボタンには、プラットフォームごとに 1 つずつファイルがあります。
src/components ディレクトリ内に、円形ボタン用の 3 つのファイルを作成します。
上記のコードが何をしているのか確認しましょう。
- Android では、
FloatingActionButtonが Material 3 のフローティングアクションボタンを表示します。sizeとclipモディファイアで 84 dp の円形にし、Iconが@expo/material-symbolsの add.xml アイコンを表示します。 - iOS では、
Buttonはplainスタイルを使用し、そのラベルは SF Symbols のImageです。frameとbackgroundモディファイアで、アイコンの周りに 84 ポイントの黄色い円を描画します。 - web では、第 3 章の button.tsx と同様に、circle-button.tsx は
PressableとSymbolViewを使用します。
他の 2 つのボタンは、テキストラベルの上にアイコンを表示します。src/components ディレクトリ内に、アイコンボタン用の 3 つのファイルを作成します。このコンポーネントは 3 つのプロパティを受け取ります。
icon: プラットフォームごとのアイコンです。Android は@expo/material-symbolsの XML アイコン、iOS は SF Symbols の名前、web は Material Symbols の名前を使用します。label: ボタンに表示されるテキストラベルです。onPress: ユーザーがボタンを押したときに実行される関数です。
Android では、Column が Icon を Text の上に配置します。iOS では、VStack が同じ役割を果たします。第 3 章の Button のファイルと同様に、3 つのファイルはすべて同じプロパティを受け付けます。
src/components ディレクトリには、各ボタンに 3 つずつファイルが含まれるようになりました。
srccomponentsbutton.android.tsxAndroid で使用button.ios.tsxiOS で使用button.tsxweb で使用circle-button.android.tsxAndroid で使用circle-button.ios.tsxiOS で使用circle-button.tsxweb で使用icon-button.android.tsxAndroid で使用icon-button.ios.tsxiOS で使用icon-button.tsxweb で使用image-viewer.tsxsrc/app/(tabs)/index.tsx 内で:
CircleButtonとIconButtonコンポーネントをインポートして表示できるようにします。- これらのボタン用に 3 つのプレースホルダー関数を追加します。
onReset()関数はユーザーがリセットボタンを押したときに実行され、画像ピッカーのボタンが再度表示されるようにします。残りの 2 つの関数の機能は後で実装します。 - 各
IconButtonのiconプロパティに、プラットフォームごとのアイコンを渡します。
オプションボタンは、Choose a photo ボタンと Use this photo ボタンと同じ footerContainer スタイルを使用します。そのため、画面上の同じ位置、つまりタブバーの上に表示されます。
Android、iOS、web でアプリを確認してみましょう。
3
ボトムシートで絵文字ピッカーを作成する
ボトムシートでは、利用可能な絵文字のリストからユーザーが絵文字を選択できます。src/components ディレクトリ内に emoji-picker.tsx ファイルを作成します。このコンポーネントは 3 つのプロパティを受け取ります。
isVisible: ボトムシートを表示するかどうかを決定するブール値です。onClose: ボトムシートを閉じる関数です。children: 後で絵文字のリストを表示するために使用します。
上記のコードが何をしているのか確認しましょう。
BottomSheetコンポーネントは、デフォルトテンプレートにすでに含まれている@expo/uiから提供されます。Android では Material 3 のボトムシートを表示します。iOS では SwiftUI のシートを表示します。web では、ページ下部にシートを表示します。isPresentedプロパティはisVisibleの値を受け取り、ボトムシートが開いているか閉じているかを制御します。onDismissプロパティは、ユーザーがボトムシートを閉じたときにonCloseを呼び出します。ユーザーは、ボトムシートを下にスワイプするか、ボトムシートの外側をタップして閉じることができます。Android では、戻るボタンでも閉じます。web では、Esc キーでも閉じます。snapPointsプロパティは、ボトムシートが停止できる高さを設定します。'half'の値は、画面の高さの約半分でボトムシートを開きます。containerColorプロパティは、アプリの背景に合わせてボトムシートの背景色を設定します。RNHostViewコンポーネントは、<View>や<Text>などの React Native のビューをボトムシート内に表示します。
RNHostView とは何ですか?
Android と iOS では、BottomSheet は Jetpack Compose と SwiftUI のネイティブビューです。その中に React Native のビューを表示するには、それらを RNHostView でラップします。これは Host と逆方向に機能します。Host は、第 3 章 で React Native のビュー内に Expo UI コンポーネントを表示するために使用しました。BottomSheet は独自の Host を作成するため、Host でラップする必要はありません。詳細については、RNHostView を参照してください。
それでは、src/app/(tabs)/index.tsx を変更しましょう。
<EmojiPicker>コンポーネントをインポートします。useStateフックでisModalVisible状態変数を作成します。デフォルト値はfalseで、ユーザーがボタンを押すまでボトムシートは非表示のままです。onAddSticker()関数内のコメントを置き換えて、ユーザーがボタンを押したときにisModalVisible変数をtrueに更新します。これで絵文字ピッカーが開きます。isModalVisible状態変数を更新するonModalClose()関数を作成します。Indexコンポーネントの末尾に<EmojiPicker>コンポーネントを配置します。
このステップ完了後の結果は次のとおりです。
4
絵文字のリストを表示する
ボトムシートのコンテンツに絵文字のグリッドを追加しましょう。これには React Native の <FlatList> コンポーネントを使用します。
src/components ディレクトリ内に emoji-list.tsx ファイルを作成し、次のコードを追加します。
上記のコードが何をしているのか確認しましょう。
emoji配列は絵文字画像を保持します。値が変わることはないため、コンポーネントの外側に置いています。<FlatList>コンポーネントは、dataプロパティの値としてemoji配列を受け取ります。renderItemプロパティはdataから各アイテムを受け取り、<Pressable>でラップしたImageコンポーネントを返します。ユーザーが絵文字を押すと、onSelectがその絵文字を受け取り、onCloseModalがボトムシートを閉じます。numColumnsプロパティは、リストを 3 列のグリッドとして表示します。columnWrapperStyleプロパティは、グリッドの各行のスタイルを設定します。
次に、src/app/(tabs)/index.tsx を更新して <EmojiList> コンポーネントをインポートし、<EmojiPicker> コンポーネント内のコメントを次のコードスニペットに置き換えます。
EmojiList コンポーネントでは、onSelect プロパティで絵文字を選択し、選択後に onCloseModal でボトムシートを閉じます。
Android、iOS、web でアプリを確認してみましょう。
5
選択した絵文字を表示する
次に、画像の上に絵文字ステッカーを配置します。src/components ディレクトリに新しいファイルを作成し、emoji-sticker.tsx という名前にします。そして次のコードを追加します。
このコンポーネントは 2 つのプロパティを受け取ります。
imageSize:Indexコンポーネント内で定義された値です。次の章で、タップ時に画像サイズを変更するために使用します。stickerSource: 選択された絵文字画像のソースです。
このコンポーネントを src/app/(tabs)/index.tsx ファイルでインポートし、Index コンポーネントを更新して画像上に絵文字ステッカーを表示します。pickedEmoji 状態が undefined でないかをチェックします。
Android、iOS、web でアプリを確認してみましょう。
まとめ
第 5 章:モーダルを作成する
絵文字ピッカーのモーダルを作成し、絵文字を選択して画像の上に表示するロジックの実装が完了しました。
次の章では、絵文字をドラッグしたり、タップでサイズを拡大縮小したりする、ジェスチャーを使ったユーザー操作を追加します。