RORK LABEN
TOOLING — Rorkの開発者向けリポジトリが動き続けています。rork-xcodeが7月16日、rork-deviceが7月15日、rork-plistが7月13日に更新されましたOPUS46 — RorkでClaude Opus 4.6が稼働しています。Rork MaxはClaude Codeを土台にアプリを組み立てる設計ですSIM — ブラウザ上で動くクラウドのiOSシミュレータを備え、実機へのインストールは1クリック、App Storeへの提出は2クリックと案内されていますMAX — Rork MaxはReact Nativeではなく純粋なSwiftを出力します。iPhone・iPad・Apple Watch・Apple TV・Vision Pro、そしてiMessageまでが射程ですNATIVE — HealthKit、ARKitとLiDAR、NFC、Dynamic Island、Live Activities、Metalによる3D、Core MLのオンデバイス推論まで扱えますSEED — RorkはLeft Lane Capitalが主導する1,500万ドルのシードラウンドを実施し、Peak XVとa16z Speedrunが参加しましたTOOLING — Rorkの開発者向けリポジトリが動き続けています。rork-xcodeが7月16日、rork-deviceが7月15日、rork-plistが7月13日に更新されましたOPUS46 — RorkでClaude Opus 4.6が稼働しています。Rork MaxはClaude Codeを土台にアプリを組み立てる設計ですSIM — ブラウザ上で動くクラウドのiOSシミュレータを備え、実機へのインストールは1クリック、App Storeへの提出は2クリックと案内されていますMAX — Rork MaxはReact Nativeではなく純粋なSwiftを出力します。iPhone・iPad・Apple Watch・Apple TV・Vision Pro、そしてiMessageまでが射程ですNATIVE — HealthKit、ARKitとLiDAR、NFC、Dynamic Island、Live Activities、Metalによる3D、Core MLのオンデバイス推論まで扱えますSEED — RorkはLeft Lane Capitalが主導する1,500万ドルのシードラウンドを実施し、Peak XVとa16z Speedrunが参加しました
記事一覧/Rork入門
Rork入門/2026-04-02初級

Rork アプリのスプラッシュスクリーンをカスタマイズする — expo-splash-screen で起動画面を演出する方法

Rork × Expo アプリのスプラッシュスクリーン(起動画面)をカスタマイズする方法を解説。expo-splash-screen を使ったロゴ表示、背景色設定、非同期処理完了まで画面を保持するテクニックを初心者向けに丁寧に説明します。

スプラッシュスクリーン起動画面expo-splash-screenExpo149React Native209アプリデザイン

自分の作ったアプリを初めて実機で起動したとき、ロゴが出るより先に白い画面が一瞬だけよぎるのが気になって、その0.5秒をどう埋めるかに半日を費やしたことがあります。スプラッシュスクリーンは、ユーザーがアプリと最初に交わす視線です。

アプリを起動したとき、最初の0.5〜2秒の間に表示される画面を**スプラッシュスクリーン(Splash Screen)**といいます。iOS ではローンチスクリーンとも呼ばれ、アプリが初期化を完了するまでの間、ユーザーに表示されます。

デフォルトのままにしておくと白い画面や無機質な画面が表示されますが、ここを丁寧に整えるだけで、アプリ全体の印象が大きく変わります。スプラッシュスクリーンは、フォントの読み込みや認証チェックといった起動直後の準備を済ませる絶好のタイミングでもあります。Rork で生成した Expo アプリのスプラッシュ画面を、app.json の基本設定からフェードアウトの演出まで、順を追って整えていきましょう。

expo-splash-screen とは

Expo が公式に提供しているライブラリ expo-splash-screen を使うと、JavaScript の初期化が完了するまでネイティブのスプラッシュスクリーンを表示し続けることができます。

主なメリットは以下の通りです。

  • 白い画面のちらつき防止: デフォルトでは JS バンドルのロード中に白い画面が一瞬表示されますが、expo-splash-screen がこれを防ぎます
  • 非同期処理の完了を待てる: フォントの読み込みや認証トークンの確認など、アプリに必要な準備が整うまでスプラッシュ画面を保持できます
  • iOS・Android・Web に対応: 1つの設定で全プラットフォームに対応できます

app.json でスプラッシュ画像と背景色を設定する

まず、プロジェクトルートの app.json(または app.config.js)でスプラッシュの基本設定を行います。

{
  "expo": {
    "name": "MyApp",
    "splash": {
      "image": "./assets/splash.png",
      "resizeMode": "contain",
      "backgroundColor": "#FFFFFF"
    },
    "ios": {
      "splash": {
        "image": "./assets/splash.png",
        "resizeMode": "contain",
        "backgroundColor": "#FFFFFF",
        "tabletImage": "./assets/splash-tablet.png"
      }
    },
    "android": {
      "splash": {
        "image": "./assets/splash.png",
        "resizeMode": "contain",
        "backgroundColor": "#FFFFFF",
        "mdpi": "./assets/splash-mdpi.png",
        "hdpi": "./assets/splash-hdpi.png",
        "xhdpi": "./assets/splash-xhdpi.png",
        "xxhdpi": "./assets/splash-xxhdpi.png",
        "xxxhdpi": "./assets/splash-xxxhdpi.png"
      }
    }
  }
}

設定のポイントをまとめます。

  • image: スプラッシュ画面に表示する画像。PNG 形式で、サイズは 1242×2688px 以上を推奨します(高解像度 iPhone に対応するため)
  • resizeMode: "contain"(画像全体を収める)または "cover"(画面いっぱいに表示)を選びます。ロゴなら contain、フルスクリーンの背景画像なら cover が適しています
  • backgroundColor: 画像の余白部分や画像が読み込まれる前に表示される背景色。ロゴの背景色と統一しましょう

expo-splash-screen を使って非同期処理を待つ

app.json の設定だけでもスプラッシュは表示されますが、アプリが起動直後に必要な処理(フォントの読み込み、認証チェックなど)が終わる前にスプラッシュが消えてしまうと、ちらつきが発生します。expo-splash-screen を使って適切なタイミングで非表示にしましょう。

// app/_layout.tsx
import { useEffect, useState } from 'react';
import * as SplashScreen from 'expo-splash-screen';
import * as Font from 'expo-font';
import { View } from 'react-native';
 
// アプリの準備が整うまでスプラッシュスクリーンを非表示にしない
SplashScreen.preventAutoHideAsync();
 
export default function RootLayout() {
  const [appIsReady, setAppIsReady] = useState(false);
 
  useEffect(() => {
    async function prepare() {
      try {
        // フォントの読み込みや初期データ取得など、必要な準備をここで行う
        await Font.loadAsync({
          'CustomFont-Regular': require('../assets/fonts/CustomFont-Regular.ttf'),
        });
 
        // 必要に応じてAPIリクエストや認証チェックも追加できる
        // await checkAuthStatus();
 
        // 意図的に少し待たせたい場合(例:アニメーションを見せたい)
        // await new Promise(resolve => setTimeout(resolve, 1000));
 
      } catch (e) {
        // 準備中のエラーは警告として記録し、アプリは起動させる
        console.warn('アプリ起動準備中にエラーが発生しました:', e);
      } finally {
        // 準備完了フラグをセット
        setAppIsReady(true);
      }
    }
 
    prepare();
  }, []);
 
  const onLayoutRootView = async () => {
    if (appIsReady) {
      // ルートViewが描画されたタイミングでスプラッシュを非表示にする
      await SplashScreen.hideAsync();
    }
  };
 
  if (!appIsReady) {
    // アプリの準備ができるまで何も描画しない(スプラッシュが表示し続ける)
    return null;
  }
 
  return (
    <View style={{ flex: 1 }} onLayout={onLayoutRootView}>
      {/* ここにアプリのルートナビゲーションを配置 */}
    </View>
  );
}

このコードの流れを整理すると次のようになります。

  1. SplashScreen.preventAutoHideAsync() を呼び出し、自動的に非表示になるのを防ぐ
  2. useEffect 内でフォント読み込みや認証チェックなどの準備処理を実行する
  3. 準備が完了したら setAppIsReady(true) を呼ぶ
  4. ルートの View が描画(onLayout が発火)したタイミングで SplashScreen.hideAsync() を呼び、スプラッシュを非表示にする

カスタムアニメーションでスプラッシュを演出する

デフォルトの SplashScreen.hideAsync() はスパッと消えるだけですが、Animated API と組み合わせることで、フェードアウトや縮小アニメーションを付けられます。

import { useEffect, useRef, useState } from 'react';
import * as SplashScreen from 'expo-splash-screen';
import { Animated, Image, StyleSheet, View } from 'react-native';
 
SplashScreen.preventAutoHideAsync();
 
export default function AnimatedSplash({ children }: { children: React.ReactNode }) {
  const [isAppReady, setIsAppReady] = useState(false);
  const [isSplashAnimationComplete, setIsSplashAnimationComplete] = useState(false);
  const animation = useRef(new Animated.Value(1)).current; // 不透明度 1 からスタート
 
  useEffect(() => {
    async function prepare() {
      // 必要な準備処理
      await new Promise(resolve => setTimeout(resolve, 500));
      setIsAppReady(true);
    }
    prepare();
  }, []);
 
  useEffect(() => {
    if (isAppReady) {
      // アプリ準備完了後、フェードアウトアニメーションを開始
      Animated.timing(animation, {
        toValue: 0,         // 不透明度を 0 にする
        duration: 500,      // 0.5秒かけてフェードアウト
        useNativeDriver: true,
      }).start(async () => {
        // アニメーション完了後にスプラッシュを非表示
        await SplashScreen.hideAsync();
        setIsSplashAnimationComplete(true);
      });
    }
  }, [isAppReady]);
 
  return (
    <View style={{ flex: 1 }}>
      {/* アプリ本体(スプラッシュの下に先に描画しておく)*/}
      {isAppReady && children}
 
      {/* カスタムスプラッシュオーバーレイ */}
      {!isSplashAnimationComplete && (
        <Animated.View
          pointerEvents="none"
          style={[StyleSheet.absoluteFill, { backgroundColor: '#FFFFFF', opacity: animation }]}
        >
          <Image
            source={require('../assets/splash.png')}
            style={{ flex: 1, resizeMode: 'contain' }}
          />
        </Animated.View>
      )}
    </View>
  );
}

このパターンでは、スプラッシュ画面の下にアプリ本体を先に描画し始めることで、アニメーション完了後に素早くメイン画面が表示される効果があります。

Rork でのプロンプト例

Rork の AI チャットでこのような指示をすると、スプラッシュスクリーンの設定を反映したコードを生成してもらえます。

アプリ起動時にスプラッシュスクリーンを表示したい。
・expo-splash-screen を使って、フォント読み込みが完了するまでスプラッシュを表示し続ける
・スプラッシュが消えるときにフェードアウトアニメーションを付ける
・app.json のスプラッシュ設定も教えてほしい

生成されたコードを元に、画像パスや背景色を自分のブランドに合わせて調整していきましょう。

実際に運用してみて気づいた、見落としがちな勘所

ドキュメント通りに設定しても、実機で起動すると微妙な違和感が残ることがあります。私自身、個人開発でアプリを公開したとき、ここで二つの小さな落とし穴にはまりました。

一つは背景色です。backgroundColor をメイン画面の背景と完全に揃えていないと、スプラッシュが消えた瞬間に色がパッと切り替わり、まるで画面が点滅したように見えてしまいます。ネイビーのスプラッシュから白い画面へ飛んだとき、自分でも「今ちらついた」と感じて、ようやく原因に気づきました。スプラッシュの背景色と、最初に描画される画面の背景色は、同じ値に統一しておくと安心です。

もう一つは表示時間です。準備処理が一瞬で終わると、スプラッシュが速く消えすぎて「光が一度よぎっただけ」のように見えてしまいます。逆に長く保持しすぎると、起動が重いアプリだと誤解されます。私の体感では、最低表示時間を 600〜800ミリ秒ほど確保すると、速すぎず遅すぎず、落ち着いて見えました。私はこの下限値を、アプリが起動時に読み込むデータ量に合わせて少しずつ調整してきました。setTimeout で意図的に下限を設けるかどうかは、扱うデータ量に合わせて調整してみてください。

よくあるエラーと対処法

スプラッシュ画像が引き伸ばされて表示される

resizeMode"cover" になっている場合に起こりやすいです。ロゴ画像なら "contain" に変更してください。また、画像ファイルのサイズが小さすぎると荒くなるため、1242×2688px 以上を用意しましょう。

iOS でスプラッシュが表示されない

app.jsonios.splash セクションが正しく設定されているか確認してください。EAS Build でビルドしている場合は、eas build を再実行して設定を反映させる必要があります。

preventAutoHideAsync を呼んでも自動で消えてしまう

コンポーネントのアンマウントや不要な再レンダリングによって hideAsync が意図せず呼ばれている可能性があります。SplashScreen.hideAsync() を呼んでいる箇所が1つだけであることを確認してください。

まとめ

ここではRork で作成した Expo アプリのスプラッシュスクリーンをカスタマイズする方法を解説しました。

  • app.json でスプラッシュ画像・背景色・表示モードを設定する
  • expo-splash-screenpreventAutoHideAsynchideAsync を使って、非同期処理が完了するまでスプラッシュを保持する
  • Animated API と組み合わせることで、フェードアウトなどのカスタムアニメーションを実装できる

スプラッシュスクリーンはアプリの顔です。ほんの少しの工夫で、ユーザーが最初に受け取る印象は大きく変わります。UIデザイン全般をさらに磨きたい方は、Rork アプリの UX デザインパターン完全ガイド もあわせてご覧ください。画面設計からインタラクション、マイクロアニメーションまで実践的に学べます。

Expo のスプラッシュ機能の網羅的な仕様は、Expo 公式ドキュメント が一次情報として確実です。

シェア

お読みいただきありがとうございます

Rork Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

Rork 入門2026-05-05
ネイティブアプリと PWA、どちらを選ぶべきか — Rork を使う前に整理しておきたい3つの判断軸
ネイティブアプリと PWA の違いを機能差で整理し、Rork でアプリを作るべきかを判断できます。プッシュ通知・カメラ・App Store 公開など具体的なコード例と判断基準を紹介します。
Rork 入門2026-03-28
Rork アプリの UX デザインパターン — ユーザー体験を劇的に向上させる画面設計・インタラクション・マイクロアニメーションの実践テクニック
Rork で作るアプリのUXを劇的に改善する実践ガイド。画面レイアウト設計、ナビゲーション構造、マイクロインタラクション、オンボーディングフロー、アクセシビリティまで、プロ品質のアプリに仕上げるデザインパターンを体系的に解説します。
Rork 入門2026-03-24
Rork でカレンダー・スケジュール管理アプリを作る — 初心者向け完全チュートリアル
Rork を使ってカレンダー・スケジュール管理アプリをゼロから作る方法を初心者向けに解説します。予定の追加・編集・削除、リマインダー通知まで、ステップバイステップで実装していきましょう。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →