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が参加しました
記事一覧/開発ツール
開発ツール/2026-04-15中級

Rorkアプリでキーボードが入力フィールドを隠す問題の完全対処ガイド

Rorkアプリでキーボードが表示されるとテキスト入力フィールドが隠れる問題の原因と解決策を解説します。KeyboardAvoidingView・ScrollView・useKeyboard フックを使った実践的な対処法を紹介します。

Rork515キーボード2KeyboardAvoidingViewReact Native209Expo149トラブルシューティング77フォーム3

フォーム画面を作ったとき、メールアドレスや本文を入力しようとするとキーボードが開いて下のフィールドが完全に見えなくなる——Rork でアプリを開発していると必ずといっていいほど直面する問題です。しかもこの現象、iOS と Android で挙動が微妙に違うので、片方で直したつもりがもう片方で再発する、という厄介な性格があります。

発生パターン別に原因を整理し、実際に動くコードとともに解決策を順番にご紹介します。

なぜキーボードが入力フィールドを隠すのか

React Native(Rork が内部で使うフレームワーク)では、ソフトウェアキーボードが展開されてもレイアウトは自動的に押し上げられません。Webブラウザとは異なり、キーボードの領域分だけ表示エリアが縮む仕組みがデフォルトで有効化されているわけではないのです。

iOS は behavior="padding" で比較的素直に対応できますが、Android は windowSoftInputMode の設定によって挙動が変わります。Expo managed workflow では app.json の設定でコントロールできます。

まず確認すること:app.json の softwareKeyboardLayoutMode

{
  "expo": {
    "android": {
      "softwareKeyboardLayoutMode": "pan"
    }
  }
}

Expo では softwareKeyboardLayoutMode"pan" にするとキーボード表示時に画面全体が上にパンします。"resize" にするとコンテンツ領域が縮小されます。どちらが適しているかはアプリの構造によって変わりますが、ほとんどのフォーム画面では "pan" のほうが自然に見えます。

ただし "pan" にしても iOS では効果がなく、Android 専用の設定です。iOS には別のアプローチが必要です。

基本パターン:KeyboardAvoidingView を使う

import {
  KeyboardAvoidingView,
  Platform,
  ScrollView,
  TextInput,
  StyleSheet,
  View,
} from 'react-native';
 
export default function ContactForm() {
  return (
    // Platform.OS で iOS / Android を分岐するのがポイント
    <KeyboardAvoidingView
      style={styles.container}
      behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
      keyboardVerticalOffset={Platform.OS === 'ios' ? 90 : 0}
    >
      <ScrollView
        contentContainerStyle={styles.scrollContent}
        keyboardShouldPersistTaps="handled"
      >
        <TextInput
          style={styles.input}
          placeholder="名前"
          returnKeyType="next"
        />
        <TextInput
          style={styles.input}
          placeholder="メールアドレス"
          keyboardType="email-address"
          returnKeyType="next"
        />
        <TextInput
          style={styles.input}
          placeholder="お問い合わせ内容"
          multiline
          numberOfLines={6}
          textAlignVertical="top"
        />
      </ScrollView>
    </KeyboardAvoidingView>
  );
}
 
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
  },
  scrollContent: {
    padding: 16,
    paddingBottom: 40, // キーボードが閉じたあとの余白
  },
  input: {
    borderWidth: 1,
    borderColor: '#ddd',
    borderRadius: 8,
    padding: 12,
    marginBottom: 16,
    fontSize: 16,
  },
});

重要なポイントが2つあります。

  1. behavior プロパティを必ず Platform.OS で分岐すること。iOS は 'padding'、Android は 'height' が基本です。undefined のままにすると iOS でまったく機能しません。

  2. keyboardVerticalOffset でナビゲーションバーの高さを調整すること。Expo Router のスタック画面では通常 90 前後が適切ですが、カスタムヘッダーを使っている場合は実測して合わせてください。

よくある間違い:ScrollView を忘れる

KeyboardAvoidingView だけ追加しても、中に ScrollView がなければ画面の内容が画面外に飛び出したとき追いかけられません。フォームの項目が画面に収まりきらない場合は必ず ScrollView を組み合わせてください。

また keyboardShouldPersistTaps="handled"ScrollView に設定しないと、フィールド外をタップしてもキーボードが閉じなかったり、タップがボタンに届かないトラブルが起きます。これは忘れがちな設定です。

パターン2:useKeyboard フックで柔軟に制御する

KeyboardAvoidingView の動作が思い通りにならないケース(ボトムシートと組み合わせた時、アニメーション中にズレるなど)では、キーボードの高さを直接取得して自分でレイアウトを調整する方法が確実です。

import { useEffect, useState } from 'react';
import { Keyboard, KeyboardEvent, Platform } from 'react-native';
 
// キーボードの高さをリアルタイムに取得するカスタムフック
export function useKeyboardHeight() {
  const [keyboardHeight, setKeyboardHeight] = useState(0);
 
  useEffect(() => {
    const showEvent =
      Platform.OS === 'ios' ? 'keyboardWillShow' : 'keyboardDidShow';
    const hideEvent =
      Platform.OS === 'ios' ? 'keyboardWillHide' : 'keyboardDidHide';
 
    const showSub = Keyboard.addListener(
      showEvent,
      (e: KeyboardEvent) => {
        setKeyboardHeight(e.endCoordinates.height);
      }
    );
    const hideSub = Keyboard.addListener(hideEvent, () => {
      setKeyboardHeight(0);
    });
 
    return () => {
      showSub.remove();
      hideSub.remove();
    };
  }, []);
 
  return keyboardHeight;
}
// 使い方
export default function ChatScreen() {
  const keyboardHeight = useKeyboardHeight();
 
  return (
    <View style={{ flex: 1 }}>
      <FlatList
        data={messages}
        // ...
      />
      <View
        style={{
          paddingBottom: keyboardHeight > 0 ? keyboardHeight : 16,
          borderTopWidth: 1,
          borderTopColor: '#eee',
          padding: 8,
        }}
      >
        <TextInput placeholder="メッセージを入力..." />
      </View>
    </View>
  );
}

チャット画面のような「入力欄が画面下部に固定されている」UIではこの方法が最も安定します。keyboardHeight が変化するたびに再レンダリングが走りますが、チャット画面程度ではパフォーマンスへの影響は無視できます。

Rork Max(SwiftUI)の場合

Rork Max で SwiftUI ネイティブアプリを生成している場合は、React Native のアプローチは関係ありません。SwiftUI では .ignoresSafeArea(.keyboard)ScrollView の組み合わせが基本です。

// SwiftUI でキーボード対応フォームを作る例
struct ContactFormView: View {
    @State private var name = ""
    @State private var email = ""
    @State private var message = ""
 
    var body: some View {
        ScrollView {
            VStack(spacing: 16) {
                TextField("名前", text: $name)
                    .textFieldStyle(.roundedBorder)
                TextField("メールアドレス", text: $email)
                    .textFieldStyle(.roundedBorder)
                    .keyboardType(.emailAddress)
                TextEditor(text: $message)
                    .frame(height: 120)
                    .border(Color.gray.opacity(0.3))
            }
            .padding()
        }
        // これがないと TextEditor が画面下に来たとき隠れる
        .ignoresSafeArea(.keyboard, edges: .bottom)
    }
}

SwiftUI は iOS 15 以降、デフォルトでキーボード回避機能が内蔵されていますが、TextEditor(複数行テキスト入力)では明示的に .ignoresSafeArea(.keyboard) を指定しないと下部が隠れることがあります。

タブバーがあるとさらに複雑になる

タブベースのナビゲーション(expo-router の Tabs など)では、タブバーの高さ分だけ追加のオフセットが必要です。

import { useSafeAreaInsets } from 'react-native-safe-area-context';
 
function FormWithTabs() {
  const insets = useSafeAreaInsets();
  const TAB_BAR_HEIGHT = 49; // Expo Router のデフォルト
 
  return (
    <KeyboardAvoidingView
      style={{ flex: 1 }}
      behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
      // タブバー + セーフエリアの合計を引く
      keyboardVerticalOffset={TAB_BAR_HEIGHT + insets.bottom}
    >
      {/* フォームの内容 */}
    </KeyboardAvoidingView>
  );
}

keyboardVerticalOffset は「キーボードの基準位置をどこにするか」のオフセットです。タブバーがある画面では、タブバーの高さを正確に引いてあげないと計算がズレます。

全体を振り返って:選択肢を状況で使い分ける

最後に、どのアプローチを選ぶべきかの判断基準をまとめます。

  • シンプルなフォーム(ログイン・問い合わせ): KeyboardAvoidingView + ScrollView で十分対応できます。
  • チャット画面・下部固定の入力欄: useKeyboardHeight フックで直接高さを管理するほうが安定します。
  • Rork Max(SwiftUI): .ignoresSafeArea(.keyboard) を使い、SwiftUIの仕組みに乗りましょう。
  • タブバーありの画面: keyboardVerticalOffset にタブバーの高さを加算することを忘れないでください。

フォームのUI/UXをさらに磨きたい場合は、Rorkアプリのレイアウト・レスポンシブデザインのトラブルシューティングガイドも参考にしてください。入力バリデーションの実装についてはreact-hook-form と Zod を使ったフォームバリデーションで詳しく解説しています。

シェア

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

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

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

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

関連記事

開発ツール2026-06-29
Rork のテキスト入力にキーボード上のツールバーを足す — iOS の InputAccessoryView と Android の自前バーを1つの部品に揃える
Rork が生成した React Native アプリのテキスト入力に、キーボードの上へ固定する「完了」やクイック挿入ボタンのツールバーを足す方法です。iOS の InputAccessoryView と、Android で自前に組むバーを、1つの再利用コンポーネントへ畳む実装を実コードで残します。
開発ツール2026-05-25
Rork で targetSdkVersion 35 にしたら Android のレイアウトが下まで埋まる問題の直し方
Android 15 (API 35) で強制されるエッジ・トゥ・エッジ表示によって、Rork で生成したアプリの下部タブやヘッダーがシステムバーに食い込む問題を、react-native-edge-to-edge と useSafeAreaInsets を使って実装パターン別に解決します。
開発ツール2026-04-22
Rork のスプラッシュ画面が消えない・起動直後に白い画面が出る問題の直し方
Rork で作ったアプリのスプラッシュ画面が長時間表示されたまま止まる・起動直後に白い画面が一瞬チラつく・iOSとAndroidで見え方が違う、といった症状の原因と具体的な直し方を、実機で検証したコードとあわせてまとめました。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →