React Native Course

Day 3

Expo UI SwiftUIで3画面タブを作る

@expo/ui/swift-ui の Host と TabView を使い、Today、Tasks、Settings の3画面を切り替えられる最小構成を作ります。各画面では Text を使って、どの画面か分かる状態にします。

React Native / Expo12分

動画では、@expo/ui/swift-uiTabView を使って、TodayTasksSettings の3画面を作ります。 この記事では、HostTabViewText の役割を確認しながら、3画面を切り替えられるところまで順番に作ります。

今回作るもの

今回は、3つの画面をタブで切り替えられる構成を作ります。

作る画面は以下です。

画面役割
Today表示、レイアウト、進捗、アクションを学ぶ画面
Tasks入力、一覧、行操作を学ぶ画面
Settingsフォーム、セクション、選択系を学ぶ画面

この回では、各画面の中身は最小限にします。 src/app/index.tsxHost の中に TabView を置き、各画面では Text を使って、どの画面を表示しているか分かる状態にします。

今回使うコンポーネント

今回は、@expo/ui/swift-ui から以下のコンポーネントを使います。

コンポーネント役割
TabView複数の画面をタブで切り替える
TabView.TabTabView の中に表示する1つのタブを定義する
Host第2回で扱ったSwiftUI componentの表示土台
Text第2回で扱ったテキスト表示

第3回の主役は TabView です。 HostTabView を含む SwiftUI ツリー全体を包むために使います。 Text は各画面の最小表示として使います。

ここで使う TabView は、Expo Router のタブルートではありません。 @expo/ui/swift-ui が提供する SwiftUI component としてのタブ表示です。

作成するファイル構成

第3回では、以下のファイルを作成します。

src/
├── app/
│   └── index.tsx
└── screens/
    ├── TodayScreen.tsx
    ├── TasksScreen.tsx
    └── SettingsScreen.tsx

components/data/types/ は、必要になったタイミングで作成します。

Step 1: 画面ファイルを作る

まず、タブに表示する3つの画面を作ります。

ここでは画面の中身を作り込まず、Text だけを使います。 Host はこのあと src/app/index.tsxTabView 全体を囲むため、各画面ファイルでは重ねて使いません。

Today画面

src/screens/TodayScreen.tsx

import { Text } from "@expo/ui/swift-ui";

export function TodayScreen() {
  return <Text>Today Screen</Text>;
}

ここでは Today Screen と表示して、Today画面が開いていることを確認できるようにしています。

Tasks画面

src/screens/TasksScreen.tsx

import { Text } from "@expo/ui/swift-ui";

export function TasksScreen() {
  return <Text>Tasks Screen</Text>;
}

Tasks 画面も同じ構成です。

今後、この画面に入力フォームやタスク一覧を追加していきます。

Settings画面

src/screens/SettingsScreen.tsx

import { Text } from "@expo/ui/swift-ui";

export function SettingsScreen() {
  return <Text>Settings Screen</Text>;
}

Settings 画面も、まずは画面名だけを表示します。

第10回以降で、フォームや選択UIを追加していきます。

補足: なぜ各画面をHostで囲まないのか

ここで、各画面ファイルを Host で囲っていないことに疑問を持つかもしれません。

第2回では、Host の中に Text を置きました。 そのため、TodayScreenTasksScreenSettingsScreen でも同じように Host で囲いたくなります。

ただ、今回はこのあと src/app/index.tsxTabView 全体を Host で囲みます。

<Host style={{ flex: 1 }}>
  <TabView defaultSelection="today">
    ...
  </TabView>
</Host>

この構成では、TabView の中に表示される TodayScreenTasksScreenSettingsScreen も、すでに Host の内側に入っています。

そのため、各画面ファイル側でさらに Host を重ねる必要はありません。

この教材では、SwiftUI component を表示する入口を src/app/index.tsxHost にまとめます。 各画面ファイルでは、TextVStack など、画面の中身だけを書く方針にします。

Step 2: TabViewで3画面を切り替える

src/app/index.tsxTabView を表示します。

import { Host, TabView } from "@expo/ui/swift-ui";
import { SettingsScreen } from "../screens/SettingsScreen";
import { TasksScreen } from "../screens/TasksScreen";
import { TodayScreen } from "../screens/TodayScreen";

export default function Index() {
  return (
    <Host style={{ flex: 1 }}>
      <TabView defaultSelection="today">
        <TabView.Tab value="today" label="Today" systemImage="calendar">
          <TodayScreen />
        </TabView.Tab>
        <TabView.Tab value="tasks" label="Tasks" systemImage="checklist">
          <TasksScreen />
        </TabView.Tab>
        <TabView.Tab value="settings" label="Settings" systemImage="gearshape">
          <SettingsScreen />
        </TabView.Tab>
      </TabView>
    </Host>
  );
}

Host の中に TabView を置きます。 TabView の中には TabView.Tab を3つ置きます。

Expo Router の (tabs) ディレクトリを使う構成ではなく、1つの画面内で SwiftUI の TabView を表示する構成です。

  • Today のタブには TodayScreen
  • Tasks のタブには TasksScreen
  • Settings のタブには SettingsScreen

を入れています。

この構成にしておくと、第4回以降は src/screens/TodayScreen.tsxsrc/screens/TasksScreen.tsxsrc/screens/SettingsScreen.tsx をそれぞれ段階的に作れます。

Step 3: iOSで動作確認する

iOS Simulator で起動します。

bunx expo start --ios

以下を確認します。

  • Today を開くと Today Screen と表示される
  • Tasks を開くと Tasks Screen と表示される
  • Settings を開くと Settings Screen と表示される
  • TabView で3画面を切り替えられる

今回のポイント

今回のポイントは、画面の中身を作り込むことではありません。

TabView で3画面を切り替える土台を作り、各画面を src/screens/ に分けることです。

この形にしておくと、次回以降は1つずつ画面を作れます。

次回やること

次回から、Today 画面を作っていきます。

まずは TextLabelVStackHStackSpacer を使って、Today の基本レイアウトを作ります。

← Expo UI SwiftUI 基礎コース に戻る