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-05-20上級

Rork で VoiceOver と Dynamic Type を本番品質に整える実装メモ

Rork で出力した React Native アプリに VoiceOver・Dynamic Type・Reduce Motion を本番品質で組み込むための、ラベル設計・フォーカス管理・回帰テストまで含めた実装メモです。

アクセシビリティ4VoiceOverDynamic Type2Rork515React Native209Reduce Motion2

プレミアム記事

公開して半年ほど経った壁紙アプリに、ある日「VoiceOver で読み上げると『ボタン、ボタン、ボタン』しか言ってくれません」というレビューが届いたことがありました。星は2つ。私は2014年から個人開発でアプリを出していて、当時 iOS / Android 合わせて累計5,000万ダウンロードを少し超えたあたり——にもかかわらず、アクセシビリティの仕上げを「いつかちゃんとやる」リストに入れたまま6年以上放置していたわけです。

そのレビューをきっかけに VoiceOver を実際に当てて自分のアプリを操作してみると、視覚的には完成して見えていた画面が、音声だけでは何ひとつ意味を成していないことが分かりました。アイコンボタンには accessibilityLabel がなく、カード型のリストはタップ可能領域とラベルがバラバラに読まれ、設定画面のスイッチは状態が読み上げられありません。VoiceOver は別世界のためのものではなく、自分が普段見落としている「画面が本来伝えるべきこと」を、率直に教えてくれる検査装置だったわけです。

その後、Rork で新規にアプリを立ち上げるたびに、最初の3日間を VoiceOver と Dynamic Type の対応に丸ごと使う ようになりました。設計が固まる前に組み込んだほうが圧倒的に早く、後付けで直すよりも実装の見通しが良くなるからです。以下に、Rork で出力した React Native + Expo プロジェクトに、VoiceOver・Dynamic Type・Reduce Motion を本番品質で組み込むための実装メモを残します。公式ドキュメントには断片的にしか書かれていないラベル設計・フォーカス管理・回帰テストの落とし穴を中心に、コードと実数値で示します。

アクセシビリティ対応が個人開発の収益にも効く三つの理由

「アクセシビリティ対応は理念としては正しいけれど、個人開発の限られた時間でそこまで手を回せない」——以前の私もそう思っていました。実際に着手してみると、収益の観点でも次の3つで効いてくることが分かったので、共有しておきます。

ひとつめは App Store / Google Play の審査リスクの低下 です。Apple は明示的に拒絶することは少ないものの、Google Play の Pre-launch Report ではアクセシビリティの問題が警告として出ます。私は2024年に1本、コントラスト比と読み上げ未対応の警告だけで「審査結果待ち」が48時間延びた経験があります。リリース日を決め打ちしている個人開発では、この遅延は精神的にもけっこう堪えます。

ふたつめは Dynamic Type 対応によるレビュー評価の改善 です。日本では中高年層が壁紙アプリのコアユーザーで、システム文字サイズを「最大」または「アクセシビリティ最大」に設定している方が一定数います。私のアプリの GA4 を見ると、device.user_agentContentSizeCategoryAccessibility を含むセッションが約 7.2 % を占めていました。この層に対してテキストが切れていると、レビューの低評価が直に増えます。Dynamic Type 対応を一通り入れたあとの3ヶ月で、平均レビュー点が 4.2 から 4.5 に上がった経験があります。

みっつめは VoiceOver 対応がそのまま「画面構造の見直し」になる ことです。読み上げ順序を整える過程で、視覚的にはなんとなく機能していた UI のロジック不備が浮き彫りになります。冗長な領域、押せそうで押せない装飾、意味不明なアイコン——これらを潰した結果、Dynamic Type 対応・国際化(多言語化)・将来の iPadOS 対応が同時に楽になります。アクセシビリティは外向きの理念であると同時に、内向きの 設計レビューの強制装置 でもあるわけです。

VoiceOver のラベルを「視覚カード = 音声カード」で揃える

VoiceOver で読み上げが破綻する一番大きな原因は、視覚的にひとつのカードに見える要素が、音声では複数の独立した要素として読まれてしまうことです。例えば下のような商品カードを Rork が生成したとします。

// Before: 音声で4回スワイプしないとカード全体が伝わらない
<Pressable onPress={() => navigate('Detail', { id })}>
  <Image source={{ uri: thumbnail }} style={styles.thumb} />
  <Text style={styles.title}>{title}</Text>
  <Text style={styles.price}>{`¥${price.toLocaleString()}`}</Text>
  <View style={styles.badge}>
    <Text style={styles.badgeText}>NEW</Text>
  </View>
</Pressable>

VoiceOver はこの中の ImageTextTextText を別々の要素として認識します。スワイプ4回ぶんを使わないと「画像、タイトル、価格、NEW」と読み上げが終わりません。視覚では一目で把握できる情報なのに、音声では4ステップに分解されてしまうわけです。

これを ひとつの音声カード にまとめます。

// After: 1スワイプで意味のひと固まりとして読まれる
<Pressable
  onPress={() => navigate('Detail', { id })}
  accessible={true}
  accessibilityRole="button"
  accessibilityLabel={`${title}、価格 ${price.toLocaleString()} 円${isNew ? '、新着' : ''}`}
  accessibilityHint="ダブルタップで詳細を開きます"
>
  <Image
    source={{ uri: thumbnail }}
    style={styles.thumb}
    accessible={false} // 親が読み上げを担うので除外
  />
  <Text style={styles.title} accessible={false}>{title}</Text>
  <Text style={styles.price} accessible={false}>{`¥${price.toLocaleString()}`}</Text>
  {isNew && (
    <View style={styles.badge} accessible={false}>
      <Text style={styles.badgeText}>NEW</Text>
    </View>
  )}
</Pressable>

ポイントは3つです。親の Pressableaccessible={true}accessibilityLabel を集約し、子の ImageText には accessible={false} を明示します。accessibilityRole="button" を付けることで VoiceOver が「ボタン」と末尾に読み上げてくれるため、ユーザーは操作可能な要素だと認識できます。そして accessibilityHint で「ダブルタップで何が起きるか」を補足する——Hint は VoiceOver の設定で読み上げをオフにしているユーザーには読まれないので、Label の重複にはなりません。

数値表現にも一手間かけます。¥1,200 を VoiceOver にそのまま渡すと「えん、いち、てん、にひゃく」と読まれることがあります。Apple は通貨記号を見れば賢く読んでくれる場合もありますが、Android の TalkBack 含めて挙動が安定しないので、ラベル内では日本語に書き下す のが私の本番運用です。¥${price} ではなく ${price.toLocaleString()} 円 と書きます。

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

この記事の続きを読む

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

この記事で得られること
VoiceOver の読み上げ単位を「視覚カード = 音声カード」で揃える accessibilityElements の組み立て方
Dynamic Type 100%〜310% の全レンジで折り返さない最小レイアウトの寸法計算とフォントスケール上限の妥協点
Reduce Motion / Reduce Transparency を検出して広告ビュー・パララックスを差し替える条件分岐
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

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

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

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

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

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

関連記事

開発ツール2026-06-23
「視差効果を減らす」をオンにした人に、アニメーションをどう返すか — Expo で Reduce Motion を尊重する層を作る
iOS の「視差効果を減らす」/ Android の「アニメーションを削除」をオンにした利用者に、アニメーションをどう出し分けるか。AccessibilityInfo と Reanimated の ReduceMotion を組み合わせ、消すのではなく「穏やかな代替」を返す実装層を作ります。
開発ツール2026-06-22
Rork(Expo)のトーストは、重なっても読み上げられても崩れない設計にする
Rork が生成した React Native アプリにトースト通知を足すとき、単純な実装は『同時に2つ出ると重なる』『スクリーンリーダーに無視される』『ノッチやホームインジケータに隠れる』の3点で破綻します。ルート1か所に置くキュー設計、本体の再レンダーから切り離すアニメーション、AccessibilityInfo による読み上げ、セーフエリア対応までを動くコードで示します。
開発ツール2026-07-15
「、」が行頭に落ちた — Rork が組んだ名言カードと日本語の禁則処理
React Native の Text は日本語の行頭禁則を保証しません。実測した違反率、WORD JOINER による事前結合の実装、onTextLayout での自動監査、Rork Max(SwiftUI)との挙動差までまとめました。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →