RORK LABEN
NATIVE — Rork Max では AR / LiDAR スキャン、Metal を使った 3D、Dynamic Island、Siri Intents、HealthKit、NFC、App Clips、Core ML まで届きますIOS27 — iOS 27 Developer Beta 4 で Siri AI の対象が iPhone 15 Pro / 15 Pro Max・16 シリーズ・17 系へ広がり、応答が初期ベータより明確に速くなりましたDESIGN — iOS・iPadOS・macOS 27 向けの Apple 純正デザインキットが Figma と Sketch 向けに公開されました。新 OS の UI を組む段階で参照できますCANARY — Android 17(Cinnamon Bun)は従来の Developer Preview を廃し、継続更新される Canary ビルドへ移行しました。検証のタイミング設計が変わりますSPARK — Android 17 の Gemini Spark は、アプリを直接操作して配車の予約や注文といった複合的な作業を自動化しますSCALE — Rork は a16z から $2.8M を調達し、月間訪問は74万件規模まで伸びていますNATIVE — Rork Max では AR / LiDAR スキャン、Metal を使った 3D、Dynamic Island、Siri Intents、HealthKit、NFC、App Clips、Core ML まで届きますIOS27 — iOS 27 Developer Beta 4 で Siri AI の対象が iPhone 15 Pro / 15 Pro Max・16 シリーズ・17 系へ広がり、応答が初期ベータより明確に速くなりましたDESIGN — iOS・iPadOS・macOS 27 向けの Apple 純正デザインキットが Figma と Sketch 向けに公開されました。新 OS の UI を組む段階で参照できますCANARY — Android 17(Cinnamon Bun)は従来の Developer Preview を廃し、継続更新される Canary ビルドへ移行しました。検証のタイミング設計が変わりますSPARK — Android 17 の Gemini Spark は、アプリを直接操作して配車の予約や注文といった複合的な作業を自動化しますSCALE — Rork は a16z から $2.8M を調達し、月間訪問は74万件規模まで伸びています
記事一覧/アプリ開発
アプリ開発/2026-06-21上級

壁紙グリッドに戻ると一番上に戻ってしまう — スクロール位置を「戻る」とプロセス復帰の両方で保つ

壁紙アプリの一覧で詳細を見て戻ると先頭に飛んでしまう問題を、ナビゲーションの戻りとプロセス復帰の二つに分けて設計し直しました。getItemLayout と保存タイミング、復元時のちらつきまで含めた実装メモです。

Rork526FlatList9スクロール位置状態復元2expo11

プレミアム記事

スワイプして見ていた壁紙の一覧で、気になった一枚をタップして拡大し、戻るボタンを押す。すると一覧は一番上に戻っていて、さっきまで見ていた行を指でもう一度探し直す。個人開発で壁紙アプリを何本か運用していると、このひと手間がどれだけ離脱を生むかが、利用データからじわじわ見えてきます。

私自身、最初は「戻るときにスクロール位置を覚えておけばいい」とだけ考えていました。ところが実装してみると、位置がずれる場面は二つあって、それぞれ原因がまったく違うことに気づきます。一つは画面を行き来する「戻る」での消失。もう一つは、OS がメモリ不足でアプリを裏で落としたあと、再び開いたときの消失です。混ぜて考えると、どちらも中途半端にしか直りません。

二つの「位置ずれ」を最初に分ける

先に切り分けておきます。ここを曖昧にしたまま保存処理を足すと、不要な永続化でスクロールがかえってカクつきます。

場面何が失われるか必要な対処
詳細へ進んで戻る(スタック内)原則は失われない。タブ切替や条件付きアンマウントで失われる画面をアンマウントしない構成にする
アプリを閉じて開き直す(プロセス継続)失われない(メモリ上の状態が残る)対処不要
OS が裏で強制終了 → 再起動メモリ上の状態がすべて消えるオフセットを端末に保存して復元する

つまり、永続化が本当に要るのは三つ目だけです。一つ目はナビゲーションの構成の問題で、保存とは無関係に解けます。ここを取り違えると、毎フレーム位置をディスクに書きに行くような重い実装になりがちです。

「戻る」で先頭に飛ぶのは、たいてい画面が消えているから

ネイティブスタックのナビゲーションでは、詳細画面を上に重ねても一覧画面はマウントされたまま背後に残ります。FlatList の内部状態もそのまま残るので、戻れば同じ位置に表示されるのが本来の挙動です。

それでも先頭に飛ぶときは、一覧画面がどこかでアンマウントされています。よくあるのは次の二つです。

ひとつは、タブやセグメントの切り替えを condition ? <List/> : <Other/> のような条件付きレンダリングで実装している場合。切り替えるたびに <List/> が丸ごと作り直され、スクロール位置はゼロに戻ります。

もうひとつは、データ取得中に if (loading) return <Spinner/> で一覧そのものを差し替えている場合。再取得のたびにリストが一度消えて、再描画で先頭に戻ります。

対処はシンプルで、一覧を消さないことです。

// ❌ 切り替えのたびにListが作り直される
function Screen({ tab }: { tab: 'all' | 'favorites' }) {
  return tab === 'all' ? <WallpaperList /> : <FavoriteList />;
}
 
// ✅ 両方マウントしたまま、表示だけ切り替える
function Screen({ tab }: { tab: 'all' | 'favorites' }) {
  return (
    <>
      <View style={{ flex: 1, display: tab === 'all' ? 'flex' : 'none' }}>
        <WallpaperList />
      </View>
      <View style={{ flex: 1, display: tab === 'favorites' ? 'flex' : 'none' }}>
        <FavoriteList />
      </View>
    </>
  );
}

display: 'none' で隠す方法なら、リストはマウントされ続けてスクロール位置を保ちます。タブが二つ三つなら、この素朴なやり方で十分実用になります。読み込み中のスピナーも、リスト全体を差し替えるのではなく、上に重ねるか、リスト内のヘッダーとして出すと位置が保たれます。

ここまでで「戻る」での位置ずれの大半は消えます。残りはプロセス復帰の方です。

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

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
「戻る」での位置ずれとプロセス復帰での位置ずれは原因が別物で、対処も別という切り分け
getItemLayout で行インデックスを計算し、初回描画前に復元してちらつきを消す実装
保存を onScroll で間引き、バックグラウンド遷移で確定保存する負荷の低いタイミング設計
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

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

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

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

関連記事

アプリ開発2026-08-05
キー短縮で 19% 減らしても配信は 3% しか軽くならない — カタログ JSON の圧縮実測と配置換え
2万件の壁紙カタログJSONで5形式を実測。キー短縮はgzip後3.2%しか効かず、列指向への配置換えは26.8%減。Brotli・ページング・JSON.parse時間まで、配信サイズ設計の判断材料を数値で並べます。
アプリ開発2026-07-16
壁紙の段組みギャラリーにネイティブ広告を差し込む — 広告セルの寿命をプールで設計する
段組みギャラリーにネイティブ広告を1枚入れたところ、20分のスクロールでメモリが伸び続けました。リスト再利用と広告の寿命が噛み合わない理由から、プール方式の実装、差し込み間隔の決め方まで実測とともに残します。
アプリ開発2026-07-14
壁紙を長押しして、プレビューと保存メニューを出す — Rork の Expo アプリで context menu を組む
壁紙ギャラリーのカードを長押ししても何も起きない。iOS利用者はプレビュー付きのメニューを期待します。Pressableだけでは届かない理由から、zeegoでのネイティブcontext menu実装、スクロールとの競合解消、保存・共有アクション、Android向けの自前フォールバックまで、動くコードでまとめます。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →