本文へ移動
バージョン: 6.x

Stack Navigator

Stack Navigatorは、新しい画面がスタックの一番上に配置される、画面間の遷移をアプリで行うための方法を提供します。

デフォルトでは、Stack Navigatorは、iOSとAndroidでおなじみのルックアンドフィールに設定されています。iOSでは新しい画面が右からスライドインし、AndroidではOSのデフォルトアニメーションを使用します。しかし、アニメーションはカスタマイズしてニーズに合わせることができます。

覚えておくべきことの1つは、@react-navigation/stackは非常にカスタマイズ可能ですが、JavaScriptで実装されていることです。ネイティブを使用してアニメーションとジェスチャーを実行しますが、パフォーマンスはネイティブ実装ほど高速ではない可能性があります。多くのアプリでは問題にならないかもしれませんが、ナビゲーション中にパフォーマンスの問題が発生する場合は、ネイティブのナビゲーションプリミティブを使用する@react-navigation/native-stackの使用を検討してください。

インストール

このナビゲーターを使用するには、@react-navigation/nativeとその依存関係(このガイドに従ってください)をインストールし、@react-navigation/stackをインストールします。

npm install @react-navigation/stack

次に、Stack Navigatorに必要なライブラリをインストールして設定する必要があります。

  1. まず、react-native-gesture-handlerをインストールします。

    Expoマネージドプロジェクトを使用している場合は、プロジェクトディレクトリで次のコマンドを実行します。

    npx expo install react-native-gesture-handler

    ネイティブのReact Nativeプロジェクトを使用している場合は、プロジェクトディレクトリで次のコマンドを実行します。

    npm install react-native-gesture-handler
  2. react-native-gesture-handlerのインストールを完了するには、エントリファイル(index.jsまたはApp.jsなど)の**先頭**に次のコードを追加します(先頭であること、およびそれより前に何もないことを確認してください)。

    import 'react-native-gesture-handler';
    警告

    AndroidまたはiOS向けにビルドする場合は、この手順をスキップしないでください。スキップすると、開発中は正常に動作しても、本番環境でアプリがクラッシュする可能性があります。これは他のプラットフォームには適用されません。

  3. オプションで、@react-native-masked-view/masked-viewもインストールできます。これは、ヘッダーにUIKitスタイルのアニメーションを使用する場合(HeaderStyleInterpolators.forUIKit)に必要です。

    Expoマネージドプロジェクトを使用している場合は、プロジェクトディレクトリで次のコマンドを実行します。

    npx expo install @react-native-masked-view/masked-view

    ネイティブのReact Nativeプロジェクトを使用している場合は、プロジェクトディレクトリで次のコマンドを実行します。

    npm install @react-native-masked-view/masked-view
  4. Macを使用していてiOS向けに開発している場合は、Cocoapodsを使用してpodをインストールして、リンクを完了する必要があります。

npx pod-install ios

API定義

このナビゲーターを使用するには、@react-navigation/stackからインポートします。

import { createStackNavigator } from '@react-navigation/stack';

const Stack = createStackNavigator();

function MyStack() {
return (
<Stack.Navigator>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Notifications" component={Notifications} />
<Stack.Screen name="Profile" component={Profile} />
<Stack.Screen name="Settings" component={Settings} />
</Stack.Navigator>
);
}

プロップス

Stack.Navigatorコンポーネントは、次のプロップスを受け入れます。

id

ナビゲーターの一意のID(オプション)。これは、子ナビゲーターでこのナビゲーターを参照するために、navigation.getParentと共に使用できます。

initialRouteName

ナビゲーターの初回読み込み時にレンダリングするルートの名前。

screenOptions

ナビゲーター内の画面に使用するデフォルトのオプション。

detachInactiveScreens

非アクティブな画面をビュー階層からデタッチしてメモリを節約するかどうかを示すブール値。これにより、react-native-screensとの統合が可能になります。デフォルトはtrueです。

特定の画面でこの最適化を無効にする必要がある場合(例:フォーカスされていない場合でも画面をビューに残したい場合)、detachPreviousScreenオプションを使用します。

オプション

次のオプションを使用して、ナビゲーター内の画面を構成できます。これらは、Stack.navigatorのプロップスscreenOptionsまたはStack.Screenのプロップスoptionsで指定できます。

title

headerTitleのフォールバックとして使用できる文字列。

cardShadowEnabled

このプロップスを使用すると、遷移中にシャドウを表示できます。デフォルトはtrueです。

cardOverlayEnabled

このプロップスを使用すると、遷移中にカードの下に半透明の暗いオーバーレイを表示できます。Androidではデフォルトでtrue、iOSではfalseです。

cardOverlay

カードのオーバーレイとして表示するReact要素を返す関数。これを使用する場合は、cardOverlayEnabledtrueに設定してください。

cardStyle

スタック内のカードのスタイルオブジェクト。デフォルトの背景の代わりに使用するカスタムの背景色をここで指定できます。

{ backgroundColor: 'transparent' }を指定して、前の画面を下に見せることもできます(透明なモーダル用)。これは、モーダルダイアログなどの実装に役立ちます。透明な背景を使用する場合は、オプションでpresentation: 'modal'を指定して、前の画面がデタッチされず、下に見えているようにする必要があります。

Webでは、画面の高さがビューポートの高さと制限されません。これは、スクロール時にブラウザのアドレスバーを非表示にするためです。これが望ましい動作ではない場合は、cardStyle{ flex: 1 }に設定して、画面がビューポートを強制的に塗りつぶすようにします。

presentation

これは、レンダリングと遷移のスタイルを構成するためのいくつかのオプションを構成するショートカットオプションです。

  • card: iOSとAndroidの画面遷移にデフォルトのOSアニメーションを使用します。
  • modal: モーダルアニメーションを使用します。これはいくつかのことを変更します。
    • 別途指定しない限り、画面のheaderModescreenに設定します。
    • モーダルのプラットフォームの動作に一致するように画面アニメーションを変更します。
  • transparentModal: modalに似ています。これは次の点を変更します。
    • 別途指定しない限り、画面のheaderModescreenに設定します。
    • 画面の背景色を透明にして、前の画面が表示されるようにします。
    • 前の画面がレンダリングされたままになるようにdetachPreviousScreenオプションを調整します。
    • 前の画面が最後の位置からアニメーションされるのを防ぎます。
    • 画面アニメーションを垂直スライドアニメーションに変更します。

transparentModalのカスタマイズ方法の詳細については、透明なモーダルを参照してください。

animationEnabled

画面で遷移アニメーションを有効にするかどうか。これをfalseに設定すると、プッシュまたはポップ時に画面はアニメーションされません。iOSとAndroidではデフォルトでtrue、Webではfalseです。

animationTypeForReplace

この画面が別の画面と置き換わる際に使用するアニメーションの種類。次の値を取ります。

  • push - 新しい画面がプッシュされるアニメーションが使用されます。
  • pop - 画面がポップされるアニメーションが使用されます。

デフォルトはpushです。

popが使用されると、置き換えられる画面にpopアニメーションが適用されます。

gestureEnabled

この画面を閉じるためにジェスチャーを使用できるかどうか。iOSではデフォルトでtrue、Androidではfalseです。

Webではジェスチャーはサポートされていません。

gestureResponseDistance

画面の端からのタッチ開始の距離を上書きしてジェスチャーを認識する数値。

gestureDirectionの値に基づいて、水平方向または垂直方向の距離のいずれかを構成します。

デフォルト値は次のとおりです。

  • 50 - gestureDirectionhorizontalまたはhorizontal-invertedの場合。
  • 135 - gestureDirectionverticalまたはvertical-invertedの場合。

これはWebではサポートされていません。

gestureVelocityImpact

ジェスチャにおける速度の関連性を決定する数値。デフォルトは0.3。

これはWebではサポートされていません。

gestureDirection

ジェスチャの方向。アニメーションセクション を参照してください。

これはWebではサポートされていません。

transitionSpec

画面遷移の構成オブジェクト。アニメーションセクション を参照してください。

cardStyleInterpolator

カードの様々な部分に対する補間スタイル。アニメーションセクション を参照してください。

headerStyleInterpolator

ヘッダーの様々な部分に対する補間スタイル。アニメーションセクション を参照してください。

keyboardHandlingEnabled

falseの場合、この画面から新しい画面に移動しても、キーボードは自動的に閉じません。デフォルトはtrue

detachPreviousScreen

メモリ節約のために、前の画面をビュー階層からデタッチするかどうかを示すブール値。アクティブな画面を通して前の画面を表示する必要がある場合は、falseに設定します。detachInactiveScreensfalseに設定されていない場合にのみ適用されます。

presentationtransparentModalまたはmodalとして使用する場合、必要な画面が表示されるように自動的に調整されます。それ以外の場合は、デフォルトでtrue

freezeOnBlur

非アクティブな画面の再レンダリングを防止するかどうかを示すブール値。デフォルトはfalse。アプリケーションの先頭でreact-native-screensパッケージのenableFreeze()を実行すると、デフォルトはtrueになります。

react-native-screensバージョン >= 3.16.0が必要です。

iOSとAndroidでのみサポートされています。

ヘッダー関連オプションの一覧はこちらにあります。これらのオプションは、Stack.navigatorscreenOptionsプロパティまたはStack.Screenoptionsプロパティで指定できます。これらのオプションを使用するために、@react-navigation/elementsを直接使用する必要はありません。これらのオプションは、そのページに記載されているだけです。

それらに加えて、スタックでは以下のオプションもサポートされています。

デフォルトのヘッダーの代わりに使用するカスタムヘッダー。

ヘッダーとして表示するReact要素を返す関数を指定します。この関数は、以下のプロパティを含むオブジェクトを引数として受け取ります。

  • navigation - 現在の画面のナビゲーションオブジェクト。
  • route - 現在の画面のルートオブジェクト。
  • options - 現在の画面のオプション。
  • layout - 画面の寸法。heightwidthのプロパティを含みます。
  • progress - アニメーションの進行状況を表すアニメーションノード。
  • back - 戻るボタンのオプション。戻るボタンのラベルとして使用するtitleプロパティを含むオブジェクトを含みます。
  • styleInterpolator - ヘッダー内の様々な要素に対する補間スタイルを返す関数。

カスタムヘッダーを使用する場合は、headerModescreenに設定してください(詳細については下記を参照)。

import { getHeaderTitle } from '@react-navigation/elements';

// ..

header: ({ navigation, route, options, back }) => {
const title = getHeaderTitle(options, route.name);

return (
<MyHeader
title={title}
leftButton={
back ? <MyBackButton onPress={navigation.goBack} /> : undefined
}
style={options.headerStyle}
/>
);
};

ナビゲーター内のすべての画面のカスタムヘッダーを設定するには、ナビゲーターのscreenOptionsプロパティでこのオプションを指定します。

カスタムヘッダーを使用する場合は、2つの点に注意してください。

グリッチを避けるためにheaderStyleheightを指定する

ヘッダーの高さがデフォルトのヘッダーの高さとは異なる場合、測定が非同期であるためグリッチが発生する可能性があります。高さを明示的に指定することで、このようなグリッチを回避できます。

headerStyle: {
height: 80, // Specify the height of your custom header
};

カスタムヘッダーのスタイルを制御するため、デフォルトではこのスタイルはヘッダーに適用されません。このスタイルをヘッダーにも適用したい場合は、プロパティのheaderStyleを使用してください。

カスタムヘッダーアニメーションのためにheaderModefloatに設定する

デフォルトでは、非モーダルのiOSで複数の画面のヘッダーをレンダリングする1つのフローティングヘッダーがあります。これらのヘッダーには、スムーズに切り替わるアニメーションが含まれています。

カスタムヘッダーを指定すると、React Navigationはそれを自動的にscreenに変更します。これにより、ヘッダーは画面と一緒にアニメーションされるため、個別にアニメーションを実装する必要はありません。

しかし、ヘッダー間の異なる遷移アニメーションを持つために、フローティングヘッダーを維持したい場合があります。そのためには、オプションでheaderMode: 'float'を指定し、カスタムヘッダーのprogress.currentprogress.nextプロパティで補間する必要があります。たとえば、以下のようにすると、ヘッダーがクロスフェードします。

const opacity = Animated.add(progress.current, progress.next || 0).interpolate({
inputRange: [0, 1, 2],
outputRange: [0, 1, 0],
});

return (
<Animated.View style={{ opacity }}>{/* Header content */}</Animated.View>
);

headerMode

ヘッダーのレンダリング方法を指定します。

  • float - 上部に留まり、画面の変更に合わせてアニメーションする単一のヘッダーをレンダリングします。iOSではデフォルトです。
  • screen - 各画面にヘッダーが添付され、ヘッダーは画面と共にフェードイン/アウトします。他のプラットフォームではデフォルトです。

headerShown

画面のヘッダーを表示または非表示にするかどうか。デフォルトではヘッダーが表示されます。これをfalseに設定すると、ヘッダーが非表示になります。

headerBackAllowFontScaling

戻るボタンのタイトルフォントが、テキストサイズアクセシビリティ設定を尊重して拡大縮小されるかどうか。デフォルトはfalse。

headerBackAccessibilityLabel

ヘッダーの戻るボタンのアクセシビリティラベル。

headerBackImage

ヘッダーの戻るボタンにカスタム画像を表示するためにReact要素を返す関数。関数が使用されると、その引数オブジェクトにtintColorが渡されます。デフォルトでは、プラットフォームのデフォルトの戻るアイコン画像(iOSでは山括弧、Androidでは矢印)である戻る画像ソースを持つImageコンポーネントです。

headerBackTitle

iOSの戻るボタンで使用されるタイトル文字列。デフォルトは前のシーンのheaderTitleです。

headerBackTitleVisible

戻るボタンのタイトルの表示/非表示には妥当なデフォルトが用意されていますが、それを上書きする場合は、このオプションにtrueまたはfalseを使用できます。

headerTruncatedBackTitle

headerBackTitleが画面に収まらない場合に、戻るボタンで使用されるタイトル文字列。デフォルトは「戻る」。

headerBackTitleStyle

戻るタイトルのスタイルオブジェクト。

イベント

ナビゲーターは、特定のアクションでイベントを発生させることができます。サポートされているイベントは以下のとおりです。

transitionStart

このイベントは、現在の画面の遷移アニメーションが開始されたときに発生します。

イベントデータ

  • e.data.closing - 画面が開いているか閉じているかを示すブール値。

React.useEffect(() => {
const unsubscribe = navigation.addListener('transitionStart', (e) => {
// Do something
});

return unsubscribe;
}, [navigation]);

transitionEnd

このイベントは、現在の画面の遷移アニメーションが終了したときに発生します。

イベントデータ

  • e.data.closing - 画面が開かれたか閉じられたかを示すブール値。

React.useEffect(() => {
const unsubscribe = navigation.addListener('transitionEnd', (e) => {
// Do something
});

return unsubscribe;
}, [navigation]);

gestureStart

このイベントは、現在の画面のスワイプジェスチャが開始されたときに発生します。

React.useEffect(() => {
const unsubscribe = navigation.addListener('gestureStart', (e) => {
// Do something
});

return unsubscribe;
}, [navigation]);

gestureEnd

このイベントは、現在の画面のスワイプジェスチャが終了したときに発生します。例:画面が正常に閉じられました。

React.useEffect(() => {
const unsubscribe = navigation.addListener('gestureEnd', (e) => {
// Do something
});

return unsubscribe;
}, [navigation]);

gestureCancel

このイベントは、現在の画面のスワイプジェスチャがキャンセルされたときに発生します。例:ジェスチャによって画面が閉じられませんでした。

React.useEffect(() => {
const unsubscribe = navigation.addListener('gestureCancel', (e) => {
// Do something
});

return unsubscribe;
}, [navigation]);

ヘルパー

スタックナビゲーターは、ナビゲーションプロパティに以下のメソッドを追加します。

replace

スタック内の現在の画面を新しい画面に置き換えます。このメソッドは以下の引数を受け取ります。

  • name - 文字列 - スタックにプッシュするルートの名前。
  • params - オブジェクト - 宛先ルートに渡す画面パラメーター。
navigation.replace('Profile', { owner: 'Michaś' });

push

新しい画面をスタックの一番上にプッシュし、そこに移動します。このメソッドは以下の引数を受け取ります。

  • name - 文字列 - スタックにプッシュするルートの名前。
  • params - オブジェクト - 宛先ルートに渡す画面パラメーター。
navigation.push('Profile', { owner: 'Michaś' });

pop

現在の画面をスタックからポップし、前の画面に戻ります。オプションの引数(count)を受け取り、戻る画面数を指定できます。

navigation.pop();

popToTop

最初の画面を除くスタック内のすべての画面をポップし、最初の画面に移動します。

navigation.popToTop();

import { createStackNavigator } from '@react-navigation/stack';

const Stack = createStackNavigator();

function MyStack() {
return (
<Stack.Navigator
initialRouteName="Home"
screenOptions={{
headerMode: 'screen',
headerTintColor: 'white',
headerStyle: { backgroundColor: 'tomato' },
}}
>
<Stack.Screen
name="Home"
component={Home}
options={{
title: 'Awesome app',
}}
/>
<Stack.Screen
name="Profile"
component={Profile}
options={{
title: 'My profile',
}}
/>
<Stack.Screen
name="Settings"
component={Settings}
options={{
gestureEnabled: false,
}}
/>
</Stack.Navigator>
);
}

アニメーション

Stack Navigatorは、画面の追加または削除時の遷移アニメーションを構成するための様々なオプションを提供しています。これらの遷移アニメーションは、各画面の`options`プロップにオプションを指定することで、画面ごとにカスタマイズできます。

  • gestureDirection - スワイプジェスチャの方向

    • horizontal - 画面を閉じるためのジェスチャは左から開始し、RTLの場合は右から開始します。アニメーションでは、画面は`SlideFromRightIOS`で右からスライドし、RTLの場合は左からスライドします。
    • horizontal-inverted - 画面を閉じるためのジェスチャは右から開始し、RTLの場合は左から開始します。アニメーションでは、方向が反転しているので、画面は`SlideFromRightIOS`で左からスライドし、RTLの場合は右からスライドします。
    • vertical - 画面を閉じるためのジェスチャは上から開始します。アニメーションでは、画面は下からスライドします。
    • vertical-inverted - 画面を閉じるためのジェスチャは下から開始します。アニメーションでは、画面は上からスライドします。

    gestureDirectionと共に、一致する水平/垂直アニメーションを指定することもできます。ライブラリに含まれるアニメーションの場合、`gestureDirection`を反転したもののいずれかに設定すると、アニメーションの方向も反転します。

  • transitionSpec - アニメーションの種類(`timing`または`spring`)とそのオプション(`timing`の場合は`duration`など)を指定するオブジェクト。2つのプロパティを取ります。

    • open - 画面を追加する際の遷移の構成
    • close - 画面を削除する際の遷移の構成

    それぞれのオブジェクトは2つのプロパティを指定する必要があります。

    • animation - アニメーションに使用するアニメーション関数。サポートされる値は`timing`と`spring`です。
    • config - タイミング関数の構成オブジェクト。`timing`の場合は、`duration`と`easing`が可能です。`spring`の場合は、`stiffness`、`damping`、`mass`、`overshootClamping`、`restDisplacementThreshold`、`restSpeedThreshold`が可能です。

    springアニメーションを使用するconfigは次のようになります。

    const config = {
    animation: 'spring',
    config: {
    stiffness: 1000,
    damping: 500,
    mass: 3,
    overshootClamping: true,
    restDisplacementThreshold: 0.01,
    restSpeedThreshold: 0.01,
    },
    };

    このconfigを`transitionSpec`オプションで渡すことができます。

    <Stack.Screen
    name="Profile"
    component={Profile}
    options={{
    transitionSpec: {
    open: config,
    close: config,
    },
    }}
    />
  • cardStyleInterpolator - カードの様々な部分の補間スタイルを指定する関数。画面間を移動する際の遷移をカスタマイズできます。少なくとも空のオブジェクトを返す必要があります。コンテナ、カード自体、オーバーレイ、シャドウの補間スタイルを含む場合があります。サポートされるプロパティは次のとおりです。

    • containerStyle - カードをラップするコンテナビューのスタイル。
    • cardStyle - カードを表すビューのスタイル。
    • overlayStyle - 下にある半透明のオーバーレイを表すビューのスタイル。
    • shadowStyle - カードのシャドウを表すビューのスタイル。

    この関数は、引数に次のプロパティを受け取ります。

    • current - 現在の画面の値
      • progress - 現在の画面の進行状況値を表すアニメーションノード。
    • next - スタック内の次の画面の値。アニメーション中の画面が最後の画面の場合、`undefined`になる場合があります。
      • progress - 次の画面の進行状況値を表すアニメーションノード。
    • index - スタック内のカードのインデックス。
    • closing - カードが閉じているかどうかを表すアニメーションノード。閉じている場合は`1`、そうでない場合は`0`。
    • layouts - アニメーションに使用される様々なアイテムのレイアウト測定値。
      • screen - 画面全体のレイアウト。`height`と`width`のプロパティが含まれています。

    画面が最後ではない場合、次の画面の遷移設定が使用されます。これは、多くの遷移が前の画面のアニメーションを含むため、2つの画面で異なる種類の遷移(例えば、スライドとモーダル)を実行しないように、これら2つの遷移を一緒にする必要があるためです。前の画面をアニメーション化したいかどうかを確認するには、`next`パラメータを確認してください。このパラメータの詳細については、アニメーションセクションを参照してください。

    画面をフェードさせるだけのconfigは次のようになります。

    const forFade = ({ current }) => ({
    cardStyle: {
    opacity: current.progress,
    },
    });

    この関数を`cardStyleInterpolator`オプションで渡すことができます。

    <Stack.Screen
    name="Profile"
    component={Profile}
    options={{ cardStyleInterpolator: forFade }}
    />

    インターポレータは各画面に対して呼び出されます。例えば、スタックにAとBの2つの画面があるとします。Bはフォーカスされる新しい画面、Aは前の画面です。インターポレータは各画面に対して呼び出されます。

    • インターポレータは`B`に対して呼び出されます。ここでは、`current.progress`の値は遷移の進行状況を表し、`0`から`1`まで変化します。`B`は最後の画面なので、`next.progress`はありません。
    • インターポレータは`A`に対して呼び出されます。ここでは、現在の遷移は`B`に対して実行されているため、`current.progress`は`1`の値のまま変化しません。`next.progress`の値は`B`の進行状況を表し、`0`から`1`まで変化します。

    遷移中に両方の画面をアニメーション化したいとします。最も簡単な方法は、現在の画面と次の画面の進行状況値を組み合わせることです。

    const progress = Animated.add(
    current.progress.interpolate({
    inputRange: [0, 1],
    outputRange: [0, 1],
    extrapolate: 'clamp',
    }),
    next
    ? next.progress.interpolate({
    inputRange: [0, 1],
    outputRange: [0, 1],
    extrapolate: 'clamp',
    })
    : 0
    );

    ここでは、画面`A`には`current.progress`と`next.progress`の両方があり、`current.progress`は`1`のままで`next.progress`が変化するため、組み合わせて進行状況が`1`から`2`に変化します。画面`B`には`current.progress`のみがあり、`0`から`1`に変化します。そのため、`0-1`と`1-2`に対して異なる補間を適用して、それぞれフォーカスされている画面とフォーカスされていない画面をアニメーション化できます。

    前の画面をわずかに左に移動し、現在の画面を右端から移動させるconfigは次のようになります。

    const forSlide = ({ current, next, inverted, layouts: { screen } }) => {
    const progress = Animated.add(
    current.progress.interpolate({
    inputRange: [0, 1],
    outputRange: [0, 1],
    extrapolate: 'clamp',
    }),
    next
    ? next.progress.interpolate({
    inputRange: [0, 1],
    outputRange: [0, 1],
    extrapolate: 'clamp',
    })
    : 0
    );

    return {
    cardStyle: {
    transform: [
    {
    translateX: Animated.multiply(
    progress.interpolate({
    inputRange: [0, 1, 2],
    outputRange: [
    screen.width, // Focused, but offscreen in the beginning
    0, // Fully focused
    screen.width * -0.3, // Fully unfocused
    ],
    extrapolate: 'clamp',
    }),
    inverted
    ),
    },
    ],
    },
    };
    };
  • headerStyleInterpolator - ヘッダーの様々な部分の補間スタイルを指定する関数。少なくとも空のオブジェクトを返す必要があります。左側のラベルとボタン、右側のボタン、タイトル、背景の補間スタイルを含む場合があります。サポートされるプロパティは次のとおりです。

    • leftLabelStyle - 左側のボタン(戻るボタンのラベル)のスタイル。
    • leftButtonStyle - 左側のボタン(通常は戻るボタン)のスタイル。
    • rightButtonStyle - 右側のボタンのスタイル。
    • titleStyle - ヘッダーのタイトルテキストのスタイル。
    • backgroundStyle - ヘッダーの背景のスタイル。

    この関数は、引数に次のプロパティを受け取ります。

    • current - 現在の画面(このヘッダーを所有する画面)の値。
      • progress - 現在の画面の進行状況値を表すアニメーションノード。画面が表示され始める時が`0`、中間が`0.5`、完全に表示される時が`1`。
    • next - スタック内の次の画面の値。アニメーション中の画面が最後の画面の場合、`undefined`になる場合があります。
      • progress - 次の画面の進行状況値を表すアニメーションノード。
    • layouts - アニメーションに使用される様々なアイテムのレイアウト測定値。各レイアウトオブジェクトには`height`と`width`のプロパティが含まれています。
      • screen - 画面全体のレイアウト。
      • title - タイトル要素のレイアウト。タイトルがレンダリングされていない場合は`undefined`になる場合があります。
      • leftLabel - 戻るボタンのラベルのレイアウト。戻るボタンのラベルがレンダリングされていない場合は`undefined`になる場合があります。

    要素をフェードさせるだけのconfigは次のようになります。

    const forFade = ({ current, next }) => {
    const opacity = Animated.add(
    current.progress,
    next ? next.progress : 0
    ).interpolate({
    inputRange: [0, 1, 2],
    outputRange: [0, 1, 0],
    });

    return {
    leftButtonStyle: { opacity },
    rightButtonStyle: { opacity },
    titleStyle: { opacity },
    backgroundStyle: { opacity },
    };
    };

    この関数を`headerStyleInterpolator`オプションで渡すことができます。

    <Stack.Screen
    name="Profile"
    component={Profile}
    options={{ headerStyleInterpolator: forFade }}
    />

プリセットconfig

これらのオプションを使用すると、画面のカスタム遷移アニメーションを作成できます。また、ライブラリから様々な既製のアニメーションを含むconfigをエクスポートして使用することもできます。

TransitionSpecs

  • TransitionIOSSpec - UINavigationControllerのアニメーション設定からの正確な値。
  • FadeInFromBottomAndroidSpec - Android Nougatからのアクティビティオープンアニメーションの設定。
  • FadeOutToBottomAndroidSpec - Android Nougatからのアクティビティクローズアニメーションの設定。
  • RevealFromBottomAndroidSpec - Android Pieからのアクティビティオープンアニメーションのおおよその設定。

import { TransitionSpecs } from '@react-navigation/stack';

// ...

<Stack.Screen
name="Profile"
component={Profile}
options={{
transitionSpec: {
open: TransitionSpecs.TransitionIOSSpec,
close: TransitionSpecs.TransitionIOSSpec,
},
}}
/>;

CardStyleInterpolators

  • forHorizontalIOS - 標準的なiOSスタイルの右からのスライドイン。
  • forVerticalIOS - 標準的なiOSスタイルの下からのスライドイン(モーダルに使用)。
  • forModalPresentationIOS - iOS 13の標準的なiOSスタイルのモーダルアニメーション。
  • forFadeFromBottomAndroid - Android Oreoの標準的なAndroidスタイルの下からのフェードイン。
  • forRevealFromBottomAndroid - Android Pieの標準的なAndroidスタイルの下からのリビール。

Android Oreoスタイルの垂直画面フェードアニメーションの例の設定

import { CardStyleInterpolators } from '@react-navigation/stack';

// ...

<Stack.Screen
name="Profile"
component={Profile}
options={{
title: 'Profile',
cardStyleInterpolator: CardStyleInterpolators.forFadeFromBottomAndroid,
}}
/>;

HeaderStyleInterpolators

  • forUIKit - タイトルが戻るボタンのラベルにフェードインするヘッダーの標準的なUIKitスタイルのアニメーション。
  • forFade - ヘッダー要素の単純なフェードアニメーション。
  • forStatic - スライドする画面と共にヘッダーを移動させる単純な移動アニメーション。

タイトルが戻るボタンにフェードインするヘッダー要素のデフォルトのiOSアニメーションの例の設定

import { HeaderStyleInterpolators } from '@react-navigation/stack';

// ...

<Stack.Screen
name="Profile"
component={Profile}
options={{
title: 'Profile',
headerStyleInterpolator: HeaderStyleInterpolators.forUIKit,
}}
/>;
警告

再レンダリング時に参照が変更されないように、ファイルの最上位レベルでアニメーション設定を常に定義してください。これは、スムーズで信頼性の高い遷移アニメーションにとって重要です。

TransitionPresets

様々なネイティブアニメーションに一致するように、これらのオプションの様々なセットをバンドルした様々な遷移プリセットをエクスポートしています。遷移プリセットは、`TransitionPresets`の下でエクスポートされたアニメーション関連のいくつかの画面オプションを含むオブジェクトです。現在、次のプリセットが利用可能です。

  • SlideFromRightIOS - 標準的なiOSナビゲーション遷移。
  • ModalSlideFromBottomIOS - モーダル用の標準的なiOSナビゲーション遷移。
  • ModalPresentationIOS - 標準的なiOSモーダルプレゼンテーションスタイル(iOS 13で導入)。
  • FadeFromBottomAndroid - Android 9(Oreo)より前のAndroidでアクティビティを開いたり閉じたりするときの標準的なAndroidナビゲーション遷移。
  • RevealFromBottomAndroid - Android 9(Pie)でアクティビティを開いたり閉じたりするときの標準的なAndroidナビゲーション遷移。
  • ScaleFromCenterAndroid - Android 10以降でアクティビティを開いたり閉じたりするときの標準的なAndroidナビゲーション遷移。
  • DefaultTransition - 現在のプラットフォームのデフォルトのナビゲーション遷移。
  • ModalTransition - 現在のプラットフォームのデフォルトのモーダル遷移。

これらのプリセットをoptionsに展開して、画面のアニメーションをカスタマイズできます。

import { TransitionPresets } from '@react-navigation/stack';

// ...

<Stack.Screen
name="Profile"
component={Profile}
options={{
title: 'Profile',
...TransitionPresets.ModalSlideFromBottomIOS,
}}
/>;

ナビゲーター内のすべての画面の遷移アニメーションをカスタマイズする場合は、ナビゲーターのscreenOptionsプロパティで指定できます。

iOSモーダルプレゼンテーションスタイルの構成例

import { TransitionPresets } from '@react-navigation/stack';

// ...

<Stack.Navigator
initialRouteName="Home"
screenOptions={({ route, navigation }) => ({
headerShown: false,
gestureEnabled: true,
...TransitionPresets.ModalPresentationIOS,
})}
>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Profile" component={Profile} />
</Stack.Navigator>;

透過モーダル

透過モーダルは、画面上にオーバーレイされるモーダルダイアログのようなものです。前の画面は下に見えます。透過モーダル画面を取得するには、画面のオプションでpresentation: 'transparentModal'を指定します。

<Stack.Navigator>
<Stack.Screen name="Home" component={HomeStack} />
<Stack.Screen
name="Modal"
component={ModalScreen}
options={{ presentation: 'transparentModal' }}
/>
</Stack.Navigator>

これで、Modal画面に移動すると、背景が透明になり、Home画面が下に見えます。

presentationに加えて、モーダルダイアログのような動作を得るために、さらにいくつかのオプションを指定できます。

  • headerShown: falseでヘッダーを無効にします。
  • cardOverlayEnabled: trueでオーバーレイを有効にします(この方法ではオーバーレイをタップして画面を閉じることができません。代替手段については下記を参照してください)。

ダイアログのアニメーションをさらにカスタマイズしたい場合、またはオーバーレイをタップして画面を閉じたい場合などは、useCardAnimationフックを使用して画面内の要素をカスタマイズできます。

import {
Animated,
View,
Text,
Pressable,
Button,
StyleSheet,
} from 'react-native';
import { useTheme } from '@react-navigation/native';
import { useCardAnimation } from '@react-navigation/stack';

function ModalScreen({ navigation }) {
const { colors } = useTheme();
const { current } = useCardAnimation();

return (
<View
style={{
flex: 1,
alignItems: 'center',
justifyContent: 'center',
}}
>
<Pressable
style={[
StyleSheet.absoluteFill,
{ backgroundColor: 'rgba(0, 0, 0, 0.5)' },
]}
onPress={navigation.goBack}
/>
<Animated.View
style={{
padding: 16,
width: '90%',
maxWidth: 400,
borderRadius: 3,
backgroundColor: colors.card,
transform: [
{
scale: current.progress.interpolate({
inputRange: [0, 1],
outputRange: [0.9, 1],
extrapolate: 'clamp',
}),
},
],
}}
>
<Text>
Mise en place is a French term that literally means “put in place. It
also refers to a way cooks in professional kitchens and restaurants
set up their work stations—first by gathering all ingredients for a
recipes, partially preparing them (like measuring out and chopping),
and setting them all near each other. Setting up mise en place before
cooking is another top tip for home cooks, as it seriously helps with
organization. It’ll pretty much guarantee you never forget to add an
ingredient and save you time from running back and forth from the
pantry ten times.
</Text>
<Button
title="Okay"
color={colors.primary}
style={{ alignSelf: 'flex-end' }}
onPress={navigation.goBack}
/>
</Animated.View>
</View>
);
}

ここでは、ダイアログのスケールをアニメーション化し、ダイアログを閉じるためのオーバーレイも追加します。