取り組みの背景 — なぜ UX デザインがアプリの成否を分けるのか
App Store や Google Play には毎日数千のアプリが公開されていますが、インストール後 7 日以内に削除されるアプリは全体の約 77% にのぼるとされています。その最大の原因は「使いにくさ」、つまり UX(ユーザーエクスペリエンス)の問題です。
Rork は AI の力でアプリを素早く生成できる強力なツールですが、生成されたアプリを「使われるアプリ」にするためには、UX の知識が不可欠です。ここで扱うのはRork で開発するアプリに適用できる UX デザインパターンを体系的に解説します。単なる見た目の装飾ではなく、ユーザーの行動心理に基づいた設計原則と、それを Rork のプロンプトやコードに落とし込む具体的な方法を紹介します。
この記事の対象読者:
Rork でアプリを作ったが「なんとなく素人っぽい」と感じている方
ダウンロード数はあるのにリテンション率が低く悩んでいる方
デザイナーに依頼せずにプロ品質の UX を実現したい個人開発者
画面レイアウトの7つの基本パターン
Rork が生成するアプリの画面レイアウトには、モバイル UX で実績のあるパターンを意識的に取り入れる点が肝心です。ここでは、用途別に最適な 7 つのレイアウトパターンを紹介します。
1. フィードレイアウト(SNS・ニュース系)
縦スクロールで情報をカード形式で並べるパターンです。Instagram や X(旧 Twitter)でおなじみの構成で、ユーザーが直感的に操作できます。
// Rork で生成する際のプロンプト例:
// 「フィード画面を作成。各カードにアバター、ユーザー名、投稿時間、
// 本文、画像(オプション)、いいね・コメントボタンを配置」
const FeedCard = ({ post }) => (
< View style = { styles.card } >
{ /* ヘッダー: アバター + ユーザー情報 */ }
< View style = { styles.cardHeader } >
< Image source = { { uri: post.avatar } } style = { styles.avatar } />
< View style = { styles.userInfo } >
< Text style = { styles.userName } > { post.userName } </ Text >
< Text style = { styles.timestamp } > { post.timeAgo } </ Text >
</ View >
</ View >
{ /* コンテンツ本文 */ }
< Text style = { styles.content } > { post.body } </ Text >
{ /* 画像(存在する場合のみ表示) */ }
{ post.image && (
< Image
source = { { uri: post.image } }
style = { styles.postImage }
resizeMode = "cover"
/>
) }
{ /* アクションバー */ }
< View style = { styles.actions } >
< TouchableOpacity style = { styles.actionButton } >
< Heart size = { 20 } color = "#666" />
< Text style = { styles.actionCount } > { post.likes } </ Text >
</ TouchableOpacity >
< TouchableOpacity style = { styles.actionButton } >
< MessageCircle size = { 20 } color = "#666" />
< Text style = { styles.actionCount } > { post.comments } </ Text >
</ TouchableOpacity >
</ View >
</ View >
);
// 期待される出力:
// カード形式のフィードが縦スクロールで表示される
// 各カードにはアバター、ユーザー名、投稿時間、本文、
// オプション画像、いいね・コメントボタンが含まれる
UX ポイント: カード間の余白(spacing)は 12〜16px が適切です。詰めすぎると読みにくく、空けすぎるとスクロール量が増えて離脱の原因になります。
2. ダッシュボードレイアウト(管理・分析系)
重要な指標をグリッドで俯瞰できるパターンです。フィットネスアプリや家計簿アプリで有効です。
3. リスト+詳細レイアウト(カタログ・検索系)
一覧から項目をタップして詳細画面に遷移するマスター・ディテールパターンです。EC アプリやレシピアプリの基本形です。
4. ステップフォームレイアウト(入力・登録系)
複数のステップに分けて入力を進めるウィザード形式です。ユーザー登録や予約フローで使います。
5. タブ+カルーセルレイアウト(コンテンツ発見系)
横スワイプで複数のコンテンツカテゴリを切り替えるパターンです。動画アプリや音楽アプリで多用されます。
6. マップ+リストレイアウト(位置情報系)
地図とリストを半々で表示し、ボトムシートで詳細を引き出すパターンです。飲食店検索や不動産アプリの定番です。
7. チャットレイアウト(メッセージ系)
メッセージバブルと入力欄を組み合わせた対話型パターンです。チャットアプリはもちろん、AI アシスタント画面にも応用できます。
ナビゲーション設計 — ユーザーを迷わせない導線の作り方
ナビゲーションはアプリの背骨です。ユーザーが「今どこにいるか」「次にどこへ行けるか」を常に理解できる設計が求められます。
タブナビゲーション vs ドロワーナビゲーション
タブナビゲーション(画面下部のアイコンバー)は、主要機能が 3〜5 個の場合に最適です。ユーザーはワンタップで画面を切り替えられるため、アクセス頻度の高い機能に向いています。
一方、ドロワーナビゲーション(ハンバーガーメニュー)は機能数が多い管理系アプリに適しています。ただし、メニューを開くまで選択肢が見えないため、発見性(discoverability)が低くなります。
// Rork プロンプト例:
// 「5つのタブを持つボトムナビゲーション。
// ホーム(Home)、検索(Search)、作成(+)、通知(Bell)、プロフィール(User)」
// タブアイコンのサイズは 24-28px が推奨
// アクティブタブは色変更 + ラベル表示でフィードバック
const TAB_CONFIG = [
{ name: 'Home' , icon: Home, label: 'ホーム' },
{ name: 'Search' , icon: Search, label: '検索' },
{ name: 'Create' , icon: PlusCircle, label: '作成' },
{ name: 'Notify' , icon: Bell, label: '通知' },
{ name: 'Profile' , icon: User, label: 'マイページ' },
];
// タブバーの高さは iOS: 49pt / Android: 56dp が標準
// Safe Area を考慮して paddingBottom を追加
const styles = StyleSheet. create ({
tabBar: {
flexDirection: 'row' ,
height: Platform. OS === 'ios' ? 49 : 56 ,
borderTopWidth: StyleSheet.hairlineWidth,
borderTopColor: '#E0E0E0' ,
backgroundColor: '#FFFFFF' ,
},
tabItem: {
flex: 1 ,
alignItems: 'center' ,
justifyContent: 'center' ,
},
activeLabel: {
fontSize: 10 ,
color: '#007AFF' ,
marginTop: 2 ,
},
});
// 期待される出力:
// 5つのアイコンが均等配置されたボトムタブバー
// アクティブなタブは青色のアイコン + ラベル表示
// 非アクティブなタブはグレーのアイコンのみ
ナビゲーション階層の黄金ルール
ユーザーが目的の画面にたどり着くまでのタップ数は、最大3タップ を目安にしてください。これは「3タップルール」として広く知られている UX 原則です。
1タップ目 : タブまたはメニューから大カテゴリを選択
2タップ目 : 一覧から目的のアイテムを選択
3タップ目 : 詳細画面内でアクションを実行
Rork でアプリを設計する際、プロンプトに「主要機能への導線は3タップ以内にしてください」と明記すると、AI がこの原則に沿った画面構成を提案してくれます。
オンボーディングフロー — 初回体験を最適化する
アプリを初めて開いたユーザーの行動を決定づけるのがオンボーディング(初回導入)フローです。最初の 30 秒で「このアプリは自分に役立つ」と感じてもらえなければ、ユーザーは離脱します。
効果的なオンボーディングの3つのパターン
パターン A: ウォークスルー型(3〜4 スライド)
アプリの主要機能を 3〜4 枚のスライドで紹介する最も一般的なパターンです。各スライドには大きなイラスト、短い見出し、1〜2 行の説明文を配置します。
// オンボーディング画面のデータ構造
const ONBOARDING_SLIDES = [
{
title: 'AIでアプリを作ろう' ,
description: 'アイデアを入力するだけで、本格的なアプリが完成します' ,
icon: '🚀' ,
backgroundColor: '#F0F4FF' ,
},
{
title: 'リアルタイムプレビュー' ,
description: '作成中のアプリをその場で確認・修正できます' ,
icon: '👁️' ,
backgroundColor: '#F0FFF4' ,
},
{
title: 'ワンクリックで公開' ,
description: 'App Store・Google Playへの公開も簡単です' ,
icon: '🎉' ,
backgroundColor: '#FFF0F6' ,
},
];
// ページインジケーター: 現在のスライド位置を
// ドットの色・サイズで視覚的にフィードバック
const PageIndicator = ({ total , current }) => (
< View style = { { flexDirection: 'row' , gap: 8 } } >
{ Array. from ({ length: total }). map (( _ , i ) => (
< View
key = { i }
style = { {
width: i === current ? 24 : 8 ,
height: 8 ,
borderRadius: 4 ,
backgroundColor: i === current ? '#007AFF' : '#D1D5DB' ,
} }
/>
)) }
</ View >
);
// 期待される出力:
// 横スワイプで切り替わる3枚のオンボーディングスライド
// 下部にアニメーション付きのページインジケーター
// 最終スライドに「始める」ボタン
パターン B: プログレッシブディスクロージャー型
機能を一度に見せず、ユーザーが操作するたびに少しずつ新しい機能を紹介するパターンです。ツールチップやコーチマークを使い、実際の画面上で操作を促します。
パターン C: パーソナライズ型
初回起動時に 2〜3 問の質問をして、ユーザーの目的に合わせたホーム画面を構成するパターンです。フィットネスアプリやニュースアプリで効果的です。
オンボーディングの UX チェックリスト
スライドは最大 4 枚まで(5 枚以上は離脱率が急上昇)
「スキップ」ボタンを必ず配置する(強制は逆効果)
最終スライドの CTA ボタンは大きく、コントラストの高い色にする
アカウント登録はオンボーディング後に配置する(先に価値を見せる)
マイクロインタラクション — 「気持ちいい」を設計する
マイクロインタラクションとは、ボタンを押したとき、データを保存したとき、エラーが発生したときなど、小さな操作に対する視覚的・触覚的なフィードバックです。これが「安っぽいアプリ」と「プロのアプリ」の差を生みます。
ボタンのプレスフィードバック
ボタンを押したときに視覚的な変化がないと、ユーザーは「タップが認識されたのか」不安になります。React Native では Animated API を使って、自然な押し込み感を演出できます。
import { useRef } from 'react' ;
import { Animated, Pressable, Text, StyleSheet } from 'react-native' ;
const AnimatedButton = ({ title , onPress }) => {
const scaleAnim = useRef ( new Animated. Value ( 1 )).current;
const handlePressIn = () => {
// 押し込み: 0.96倍に縮小(100msで自然な速度)
Animated. spring (scaleAnim, {
toValue: 0.96 ,
useNativeDriver: true ,
speed: 50 ,
bounciness: 4 ,
}). start ();
};
const handlePressOut = () => {
// 離す: 元のサイズに戻る(軽いバウンス付き)
Animated. spring (scaleAnim, {
toValue: 1 ,
useNativeDriver: true ,
speed: 20 ,
bounciness: 6 ,
}). start ();
};
return (
< Pressable
onPressIn = { handlePressIn }
onPressOut = { handlePressOut }
onPress = { onPress }
>
< Animated.View
style = { [
styles.button,
{ transform: [{ scale: scaleAnim }] },
] }
>
< Text style = { styles.buttonText } > { title } </ Text >
</ Animated.View >
</ Pressable >
);
};
const styles = StyleSheet. create ({
button: {
backgroundColor: '#007AFF' ,
paddingVertical: 14 ,
paddingHorizontal: 28 ,
borderRadius: 12 ,
alignItems: 'center' ,
},
buttonText: {
color: '#FFFFFF' ,
fontSize: 16 ,
fontWeight: '600' ,
},
});
// 期待される出力:
// タップ時に軽く縮小し、指を離すとバウンスして元に戻るボタン
// ネイティブドライバーを使用するためスムーズな60fpsアニメーション
成功・エラー時のフィードバック
フォーム送信やデータ保存の結果は、即座にユーザーに伝える必要があります。
import { Animated, Text, View, StyleSheet } from 'react-native' ;
import { useRef, useEffect } from 'react' ;
// トースト通知コンポーネント
const Toast = ({ message , type = 'success' , visible }) => {
const translateY = useRef ( new Animated. Value ( - 100 )).current;
const opacity = useRef ( new Animated. Value ( 0 )).current;
useEffect (() => {
if (visible) {
// スライドイン + フェードイン
Animated. parallel ([
Animated. spring (translateY, {
toValue: 0 ,
useNativeDriver: true ,
speed: 14 ,
bounciness: 5 ,
}),
Animated. timing (opacity, {
toValue: 1 ,
duration: 200 ,
useNativeDriver: true ,
}),
]). start ();
// 3秒後に自動で消える
const timer = setTimeout (() => {
Animated. parallel ([
Animated. timing (translateY, {
toValue: - 100 ,
duration: 300 ,
useNativeDriver: true ,
}),
Animated. timing (opacity, {
toValue: 0 ,
duration: 300 ,
useNativeDriver: true ,
}),
]). start ();
}, 3000 );
return () => clearTimeout (timer);
}
}, [visible]);
const backgroundColor = type === 'success' ? '#10B981' : '#EF4444' ;
return (
< Animated.View
style = { [
styles.toast,
{ backgroundColor, transform: [{ translateY }], opacity },
] }
>
< Text style = { styles.toastIcon } >
{ type === 'success' ? '✓' : '✗' }
</ Text >
< Text style = { styles.toastMessage } > { message } </ Text >
</ Animated.View >
);
};
const styles = StyleSheet. create ({
toast: {
position: 'absolute' ,
top: 60 ,
left: 20 ,
right: 20 ,
paddingVertical: 14 ,
paddingHorizontal: 20 ,
borderRadius: 12 ,
flexDirection: 'row' ,
alignItems: 'center' ,
// シャドウで浮遊感を演出
shadowColor: '#000' ,
shadowOffset: { width: 0 , height: 4 },
shadowOpacity: 0.15 ,
shadowRadius: 12 ,
elevation: 8 ,
},
toastIcon: {
color: '#FFFFFF' ,
fontSize: 18 ,
fontWeight: '700' ,
marginRight: 10 ,
},
toastMessage: {
color: '#FFFFFF' ,
fontSize: 14 ,
fontWeight: '500' ,
flex: 1 ,
},
});
// 期待される出力:
// 画面上部からスライドインするトースト通知
// 成功時は緑色、エラー時は赤色
// 3秒後に自動フェードアウト
ローディング状態のデザイン
ローディング中の「空白画面」はユーザーに不安を与えます。スケルトンスクリーン(コンテンツの輪郭だけを表示するプレースホルダー)を使うことで、体感待ち時間を最大 30% 削減できるという研究結果もあります。
import { useRef, useEffect } from 'react' ;
import { Animated, View, StyleSheet } from 'react-native' ;
// スケルトンスクリーンのシマーエフェクト
const SkeletonLine = ({ width = '100%' , height = 16 }) => {
const shimmer = useRef ( new Animated. Value ( 0 )).current;
useEffect (() => {
// 無限ループのパルスアニメーション
Animated. loop (
Animated. sequence ([
Animated. timing (shimmer, {
toValue: 1 ,
duration: 1000 ,
useNativeDriver: true ,
}),
Animated. timing (shimmer, {
toValue: 0 ,
duration: 1000 ,
useNativeDriver: true ,
}),
])
). start ();
}, []);
const opacity = shimmer. interpolate ({
inputRange: [ 0 , 1 ],
outputRange: [ 0.3 , 0.7 ],
});
return (
< Animated.View
style = { [
styles.skeleton,
{ width, height, borderRadius: height / 2 , opacity },
] }
/>
);
};
// フィードカードのスケルトン
const FeedCardSkeleton = () => (
< View style = { styles.skeletonCard } >
< View style = { styles.skeletonHeader } >
< SkeletonLine width = { 40 } height = { 40 } />
< View style = { { marginLeft: 12 , flex: 1 } } >
< SkeletonLine width = "60%" height = { 14 } />
< View style = { { height: 6 } } />
< SkeletonLine width = "30%" height = { 10 } />
</ View >
</ View >
< View style = { { marginTop: 12 } } >
< SkeletonLine width = "100%" height = { 12 } />
< View style = { { height: 6 } } />
< SkeletonLine width = "85%" height = { 12 } />
< View style = { { height: 6 } } />
< SkeletonLine width = "70%" height = { 12 } />
</ View >
</ View >
);
const styles = StyleSheet. create ({
skeleton: {
backgroundColor: '#E5E7EB' ,
},
skeletonCard: {
padding: 16 ,
backgroundColor: '#FFFFFF' ,
marginBottom: 8 ,
},
skeletonHeader: {
flexDirection: 'row' ,
alignItems: 'center' ,
},
});
// 期待される出力:
// カードの形をした灰色のプレースホルダーがパルスアニメーション
// アバター、テキスト行の形状が実際のカードレイアウトと一致
フォーム設計 — 入力ストレスを最小化する
フォーム入力はユーザーにとって最もストレスの高い操作です。以下のパターンを適用することで、入力完了率を大幅に向上させることができます。
インラインバリデーション
入力欄ごとにリアルタイムでバリデーション結果を表示します。送信ボタンを押した後にまとめてエラーを表示する方式(一括バリデーション)に比べ、入力完了率が約 22% 向上するというデータがあります。
import { useState } from 'react' ;
import { View, TextInput, Text, StyleSheet } from 'react-native' ;
const ValidatedInput = ({ label , value , onChangeText , validate }) => {
const [ touched , setTouched ] = useState ( false );
const error = touched ? validate (value) : null ;
const isValid = touched && ! error && value. length > 0 ;
return (
< View style = { styles.inputWrapper } >
< Text style = { styles.label } > { label } </ Text >
< View
style = { [
styles.inputContainer,
error && styles.inputError,
isValid && styles.inputValid,
] }
>
< TextInput
style = { styles.input }
value = { value }
onChangeText = { onChangeText }
onBlur = { () => setTouched ( true ) }
placeholderTextColor = "#9CA3AF"
/>
{ /* 入力状態のインジケーター */ }
{ isValid && < Text style = { styles.validIcon } >✓</ Text > }
{ error && < Text style = { styles.errorIcon } >!</ Text > }
</ View >
{ /* エラーメッセージ */ }
{ error && < Text style = { styles.errorText } > { error } </ Text > }
</ View >
);
};
// 使用例
const EmailInput = () => {
const [ email , setEmail ] = useState ( '' );
const validateEmail = ( val ) => {
if ( ! val) return 'メールアドレスを入力してください' ;
if ( ! / ^ [ ^ \s@] + @ [ ^ \s@] + \. [ ^ \s@] +$ / . test (val)) {
return '正しいメールアドレス形式で入力してください' ;
}
return null ; // バリデーション成功
};
return (
< ValidatedInput
label = "メールアドレス"
value = { email }
onChangeText = { setEmail }
validate = { validateEmail }
/>
);
};
const styles = StyleSheet. create ({
inputWrapper: { marginBottom: 20 },
label: {
fontSize: 14 ,
fontWeight: '600' ,
color: '#374151' ,
marginBottom: 6 ,
},
inputContainer: {
flexDirection: 'row' ,
alignItems: 'center' ,
borderWidth: 1.5 ,
borderColor: '#D1D5DB' ,
borderRadius: 10 ,
paddingHorizontal: 14 ,
backgroundColor: '#FFFFFF' ,
},
inputError: { borderColor: '#EF4444' },
inputValid: { borderColor: '#10B981' },
input: { flex: 1 , height: 48 , fontSize: 16 , color: '#111827' },
validIcon: { color: '#10B981' , fontSize: 18 , fontWeight: '700' },
errorIcon: { color: '#EF4444' , fontSize: 18 , fontWeight: '700' },
errorText: { color: '#EF4444' , fontSize: 12 , marginTop: 4 },
});
// 期待される出力:
// フォーカスを外すと入力値をリアルタイムで検証
// 有効な入力: 緑色のボーダー + チェックマーク
// 無効な入力: 赤色のボーダー + エラーメッセージ
フォーム設計の重要原則
ラベルは入力欄の上 に配置する(プレースホルダーをラベル代わりにしない)
1画面1目的 : 登録フォームを複数ステップに分割し、各ステップは 2〜3 項目に抑える
キーボードタイプを適切に設定 : メールなら keyboardType="email-address"、電話なら keyboardType="phone-pad"
自動フォーカス移動 : 入力完了時に次の入力欄に自動でフォーカスを移す
カラーシステムとタイポグラフィ — 視覚的な一貫性を保つ
プロ品質のアプリには、一貫したカラーシステムとタイポグラフィが不可欠です。Rork にプロンプトで指示する際も、具体的な色やフォントサイズを指定することで、生成結果の品質が飛躍的に向上します。
カラーパレットの構築法
アプリのカラーパレットは、以下の 5 つのカテゴリで定義します。
// テーマカラー定義(ライト / ダークモード対応)
const COLORS = {
light: {
// プライマリ: ブランドカラー(CTA ボタン、リンク、アクセント)
primary: '#007AFF' ,
primaryLight: '#E5F0FF' ,
// セマンティック: 状態を表す色
success: '#10B981' ,
warning: '#F59E0B' ,
error: '#EF4444' ,
info: '#3B82F6' ,
// ニュートラル: テキスト、背景、ボーダー
textPrimary: '#111827' ,
textSecondary: '#6B7280' ,
textTertiary: '#9CA3AF' ,
background: '#F9FAFB' ,
surface: '#FFFFFF' ,
border: '#E5E7EB' ,
// WCAG AA準拠のコントラスト比(4.5:1以上)を確保する
},
dark: {
primary: '#60A5FA' ,
primaryLight: '#1E3A5F' ,
success: '#34D399' ,
warning: '#FBBF24' ,
error: '#F87171' ,
info: '#60A5FA' ,
textPrimary: '#F9FAFB' ,
textSecondary: '#D1D5DB' ,
textTertiary: '#9CA3AF' ,
background: '#111827' ,
surface: '#1F2937' ,
border: '#374151' ,
},
};
// 期待される出力:
// ライトモードとダークモードの両方に対応した
// 一貫性のあるカラーパレットが定義される
タイポグラフィスケール
フォントサイズには数学的なスケール(1.25倍比率)を適用すると、視覚的に調和のとれた階層構造が生まれます。
見出し1(H1) : 28px / bold — 画面タイトル
見出し2(H2) : 22px / semibold — セクションタイトル
見出し3(H3) : 18px / semibold — サブセクション
本文 : 16px / regular — 主要コンテンツ(行間 1.6)
キャプション : 14px / regular — 補助テキスト
バッジ : 12px / medium — ラベル、タグ
アクセシビリティ — すべてのユーザーに使いやすく
アクセシビリティは「あると嬉しい」機能ではなく、プロのアプリに必須の要素です。iOS の VoiceOver、Android の TalkBack に対応することで、潜在ユーザー層が広がるだけでなく、App Store のレビュー評価にもプラスの影響を与えます。
React Native でのアクセシビリティ実装
// アクセシブルなボタンコンポーネント
< TouchableOpacity
onPress = { handleSave }
accessible = { true }
accessibilityLabel = "プロフィールを保存する"
accessibilityHint = "入力したプロフィール情報をサーバーに保存します"
accessibilityRole = "button"
accessibilityState = { { disabled: ! isValid } }
>
< Text style = { styles.buttonText } >保存</ Text >
</ TouchableOpacity >
// 画像のアクセシビリティ
< Image
source = { { uri: product.image } }
style = { styles.productImage }
accessible = { true }
accessibilityLabel = { `${ product . name }の写真` }
/>
// タッチターゲットの最小サイズ: 44x44pt(Apple HIG推奨)
// Android は 48x48dp が推奨
// 期待される出力:
// VoiceOver / TalkBack が各要素を正しく読み上げ
// ボタンの役割と状態(無効/有効)を音声で伝達
Rork プロンプトへのアクセシビリティ指示テンプレート
Rork で画面を生成する際、以下のテンプレートをプロンプトに追加すると、アクセシビリティ対応のコードが生成されやすくなります。
アクセシビリティ要件:
- 全てのTouchableOpacity/Pressableに accessibilityLabel を設定
- 画像には代替テキスト(accessibilityLabel)を設定
- タッチターゲットは最小 44x44pt
- テキストのコントラスト比は WCAG AA(4.5:1)以上
- フォントサイズはユーザーの端末設定に連動(Dynamic Type対応)
Rork プロンプトに組み込める UX 指示テンプレート集
最後に、Rork でアプリを生成する際にプロンプトに追加できる UX 指示テンプレートをまとめます。これらをコピーしてプロンプトに貼り付けるだけで、生成されるアプリの UX 品質が格段に向上します。
テンプレート 1: 全般的な UX 品質指示
UXデザイン基準:
- 画面間の遷移にはフェード/スライドアニメーションを追加
- ボタンにはプレスフィードバック(scale: 0.96)を実装
- ローディング中はスケルトンスクリーンを表示
- エラー時は赤色のインラインメッセージで即座にフィードバック
- 成功時は緑色のトースト通知を表示
- カード間の余白は 12px、セクション間は 24px
テンプレート 2: フォーム画面の UX 指示
フォームUX:
- ラベルは入力欄の上に配置(プレースホルダーをラベルにしない)
- インラインバリデーション(フォーカスが外れた時点で検証)
- 有効: 緑ボーダー + チェックマーク / 無効: 赤ボーダー + エラー文
- 入力完了後に次のフィールドへ自動フォーカス
- キーボードタイプを入力内容に合わせて設定
- 送信ボタンは全フィールドが有効な場合のみアクティブ化
テンプレート 3: リスト画面の UX 指示
リストUX:
- Pull-to-Refreshで更新可能にする
- 無限スクロール(ページネーション)で追加読み込み
- 空状態にはイラスト + 説明文 + CTAボタンを表示
- 検索バーは上部に固定(スクロールで隠れない)
- リストアイテムのスワイプアクション(削除/アーカイブ)を実装
個人開発者の視点から(実体験メモ)
まとめ
UX デザインは「センス」ではなく「パターン」の蓄積です。この記事で紹介した画面レイアウトの7パターン、ナビゲーションの3タップルール、オンボーディングの設計原則、マイクロインタラクションのコード例、フォームのインラインバリデーション、カラーシステム、アクセシビリティ対応は、いずれもモバイル UX の定番パターンであり、Rork のプロンプトに組み込むことで即座に効果を発揮します。
特に個人開発者にとって、デザイナーなしでプロ品質の UX を実現できることは大きな強みです。この記事のテンプレートを活用して、あなたの Rork アプリを「インストールされるだけのアプリ」から「毎日使われるアプリ」に進化させてください。