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が参加しました
記事一覧/AIモデル
AIモデル/2026-05-03中級

Rork Max の AI × SwiftUI:生成コードをプロ品質の UX に仕上げる 4 つの実装パターン

Rork Max の AI が生成した SwiftUI コードを、ユーザーが「なめらかだ」と感じるプロ品質に仕上げる 4 つの実装パターンを解説します。スケルトン UI・アニメーション・エラー処理・ハプティクスまで、実コード付きで解説します。

Rork Max229SwiftUI63AI31UX5アニメーション10ハプティクス2iOS開発15

Rork Max で SwiftUI アプリを生成すると、最初の画面が出るまでが本当に速いですよね。数分で動く UI が出てきて「こんなに早くできるのか」と驚くのですが、そのあとに壁があります。

「なんか UI が安っぽい」「ボタンを押したときの反応が物足りない」「ローディングの見せ方が寂しい」——動いてはいるけど、プロっぽくない状態です。

Rork Max の AI は骨格を作るのが得意で、それは本当に素晴らしい能力です。ただ、細部の UX を詰めるのは今のところ人間が担う部分があります。私がアプリを公開してきた経験から、生成コードを「プロ品質」に仕上げるために毎回使う 4 つのパターンを順番にご紹介します。

AI 生成コードの「惜しい」ポイントを理解する

Rork Max の SwiftUI 生成は、機能的なコードとしては非常に完成度が高いです。データの取得、UI のレイアウト、ナビゲーション——これらは概ね正確に生成されます。

問題は「感触」の部分です。具体的には次のようなポイントが残りがちです。

  • ローディング中の見せ方: ProgressView() 一つで済ませているケースが多く、コンテンツの形に合ったプレースホルダーがない
  • 画面遷移のアニメーション: デフォルトのスライドのみで、コンテンツの特性に合った演出がない
  • エラー時の UI: "Error occurred" のテキストのみで、ユーザーがどう対処すべきかわからない
  • タッチフィードバック: ボタンを押しても反応が薄く、操作が届いた感覚がない

これらは機能ではなく「感触」の問題なので、プロンプトだけで完璧に解決するのは難しい部分でもあります。では、1 つずつ見ていきましょう。

パターン 1:ローディングをスケルトン UI で仕上げる

最も効果が大きいのがローディングの改善です。

Rork Max が生成するローディングは多くの場合、中央にスピナーが出るパターンです。これ自体は間違いではないのですが、コンテンツが多いアプリでは「空白の時間」が長く感じられます。

スケルトン UI(コンテンツの形に合ったプレースホルダー)を追加すると、体感速度が大幅に改善します。

// Rork Max が生成する典型的なパターン
struct ArticleListView: View {
    @State private var articles: [Article] = []
    @State private var isLoading = true
 
    var body: some View {
        if isLoading {
            ProgressView() // ← これをスケルトンに置き換える
        } else {
            List(articles) { article in
                ArticleRow(article: article)
            }
        }
    }
}
 
// スケルトン UI 版
struct ArticleListView: View {
    @State private var articles: [Article] = []
    @State private var isLoading = true
 
    var body: some View {
        List {
            if isLoading {
                // コンテンツの形に合ったスケルトンを 4 行表示
                ForEach(0..<4, id: \.self) { _ in
                    ArticleSkeletonRow()
                }
            } else {
                ForEach(articles) { article in
                    ArticleRow(article: article)
                }
            }
        }
        .task { await fetchArticles() }
    }
}
 
// スケルトン行コンポーネント
struct ArticleSkeletonRow: View {
    @State private var isAnimating = false
 
    var body: some View {
        VStack(alignment: .leading, spacing: 8) {
            // タイトル行のプレースホルダー
            RoundedRectangle(cornerRadius: 4)
                .fill(Color.gray.opacity(0.2))
                .frame(width: 200, height: 16)
            // 説明文のプレースホルダー
            RoundedRectangle(cornerRadius: 4)
                .fill(Color.gray.opacity(0.15))
                .frame(maxWidth: .infinity)
                .frame(height: 12)
        }
        .padding(.vertical, 8)
        .opacity(isAnimating ? 0.5 : 1.0)
        .animation(
            .easeInOut(duration: 0.9).repeatForever(autoreverses: true),
            value: isAnimating
        )
        .onAppear { isAnimating = true }
    }
}

Rork Max に「スケルトン UI を追加して」と伝えると汎用的なものになりがちです。「このリストのセル形状に合ったスケルトン行コンポーネントを作って」と具体的に指示すると、実際のレイアウトに合ったものが生成されます。

パターン 2:画面遷移に「意味のある動き」を加える

SwiftUI のデフォルト遷移はスライドです。悪くはないのですが、全画面が同じ遷移では単調になります。

iOS 18 以降で使える .navigationTransition(.zoom) は、タップしたセルから詳細画面が「広がる」ような演出で、ユーザーの空間認識と一致します。

// iOS 18+ のズームトランジション
struct ArticleListView: View {
    @Namespace private var namespace
 
    var body: some View {
        NavigationStack {
            List(articles) { article in
                NavigationLink(value: article) {
                    ArticleRow(article: article)
                }
                .matchedTransitionSource(id: article.id, in: namespace)
            }
            .navigationDestination(for: Article.self) { article in
                ArticleDetailView(article: article)
                    .navigationTransition(.zoom(sourceID: article.id, in: namespace))
            }
        }
    }
}
 
// モーダル操作(設定画面など):下からスライドアップ
.sheet(isPresented: $showSettings) {
    SettingsView()
        .presentationDetents([.medium, .large])
        .presentationDragIndicator(.visible)
}

Rork Max に「iOS 18 の zoom ナビゲーショントランジションを実装して」と伝えると対応したコードを生成してくれます。ただし、@Namespace の宣言位置を確認することをお勧めします。ビューの階層が深い場合に位置がずれることがあります。

パターン 3:エラー状態の UX を人間的に設計する

これは見落とされがちですが、ユーザー満足度に大きく影響します。

Rork Max が生成するエラー処理は機能的には正しいのですが、表示が最低限になりがちです。エラーが出た時に「何が起きたか」「どうすればいいか」が伝わる設計にします。

// エラー種別を意味別に定義
enum AppError: Error {
    case networkUnavailable
    case serverError(Int)
    case timeout
 
    var title: String {
        switch self {
        case .networkUnavailable: return "接続できませんでした"
        case .serverError:        return "サービスが一時的に利用できません"
        case .timeout:            return "時間がかかっています"
        }
    }
 
    var message: String {
        switch self {
        case .networkUnavailable:
            return "Wi-Fi またはモバイルデータ通信を確認してください"
        case .serverError(let code):
            return "しばらく経ってから再度お試しください(エラーコード: \(code))"
        case .timeout:
            return "通信速度が低下している可能性があります"
        }
    }
 
    var sfSymbol: String {
        switch self {
        case .networkUnavailable: return "wifi.slash"
        case .serverError:        return "exclamationmark.triangle"
        case .timeout:            return "clock.badge.exclamationmark"
        }
    }
}
 
// 再利用可能なエラー表示コンポーネント
struct ErrorStateView: View {
    let error: AppError
    let retryAction: () -> Void
 
    var body: some View {
        VStack(spacing: 20) {
            Image(systemName: error.sfSymbol)
                .font(.system(size: 48))
                .foregroundColor(.secondary)
 
            VStack(spacing: 8) {
                Text(error.title)
                    .font(.headline)
                Text(error.message)
                    .font(.subheadline)
                    .foregroundColor(.secondary)
                    .multilineTextAlignment(.center)
            }
 
            Button("もう一度試す", action: retryAction)
                .buttonStyle(.borderedProminent)
        }
        .padding(32)
    }
}

技術的なエラーメッセージ("URLSession error domain -1009" など)をそのまま表示するのは、ユーザーに何も伝えていないのと同じです。Rork Max にこのパターンを渡して「アプリのエラー処理をこのパターンに合わせて」と指示すると、統一感のあるエラー UI に整えてくれます。

パターン 4:ハプティクスでボタンの「確かさ」を伝える

最もシンプルで、最も即効性がある改善です。

iOS のハプティクス(触覚フィードバック)は、ユーザーが「ちゃんと操作できた」という確信を与えます。特に完了アクション、削除操作、トグル操作での差が大きいです。

// アプリ全体で使いやすくするハプティクスラッパー
struct HapticManager {
    /// 軽い確認(チェックボックス ON/OFF など)
    static func light() {
        UIImpactFeedbackGenerator(style: .light).impactOccurred()
    }
 
    /// 中程度(通常のボタンタップ)
    static func medium() {
        UIImpactFeedbackGenerator(style: .medium).impactOccurred()
    }
 
    /// 成功通知(タスク完了、保存成功)
    static func success() {
        UINotificationFeedbackGenerator().notificationOccurred(.success)
    }
 
    /// エラー通知(削除確認、操作失敗)
    static func error() {
        UINotificationFeedbackGenerator().notificationOccurred(.error)
    }
}
 
// 使用例:タスク完了ボタン
Button("完了にする") {
    HapticManager.success() // 先にハプティクス → 処理
    viewModel.completeTask()
}
 
// 使用例:スワイプ削除
.swipeActions(edge: .trailing) {
    Button(role: .destructive) {
        HapticManager.error()
        viewModel.delete(item)
    } label: {
        Label("削除", systemImage: "trash")
    }
}
 
// 使用例:トグルスイッチ
Toggle("通知をオン", isOn: $notificationsEnabled)
    .onChange(of: notificationsEnabled) {
        HapticManager.light()
    }

ハプティクスは呼び出す前(アクションの直前)に発火するのがポイントです。処理後に呼ぶと「反応が遅い」という印象になります。

Rork Max との反復改善ワークフロー

これら 4 つのパターンを Rork Max に適用する際のコツは、「一気に全部やってもらおうとしない」ことです。

私のやり方はこうです。まず Rork Max で機能を完成させて、Rork Companion を使って実機で確認しながら「詰めが必要な箇所」をメモします。そのあと 1 箇所ずつ Rork Max に追加指示します——「このローディングをスケルトンにして」「このボタンに medium ハプティクスを追加して」——という具合に。

特に SwiftUI のアニメーション系は、一つ変えると他に影響が出ることがあります。まとめて指示すると生成が複雑になりやすいので、1 回の指示で 1 箇所ずつ直していく方が確実です。

プロンプトのコツについては Rork Max プロンプト活用ガイド に詳しくまとめています。

まずはハプティクスだけでも追加してみてください。「たったこれだけの変更で、アプリの印象がガラッと変わった」と実感できるはずです。次のビルドで試してみることをお勧めします。

シェア

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

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

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

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

関連記事

AI モデル2026-05-04
Rork Max の SwiftUI 生成は「どこまでできるのか」— 実機テストで見えた可能性と限界2026
Rork MaxのSwiftUI/ネイティブアプリ生成能力を実機テストで検証。何が得意で何が苦手かを正直にまとめました。機能の宣伝ではなく、実際に使った評価です。
AI モデル2026-05-02
Rork Max で SwiftUI ネイティブアプリを生成する実務ワークフロー — 仕様書から App Store 提出までの流れ
Rork Max を使って SwiftUI のネイティブ iOS アプリを生成する際、仕様書の準備から TestFlight、App Store 申請までを通しでどう運用するか。私が個人開発で確立したワークフローを実例ベースで共有します。
AI モデル2026-04-27
Rork Max で SwiftUI ネイティブアプリを生成する — 設計から App Store リリースまでの実装ガイド
Rork Max は SwiftUI ネイティブアプリ生成の精度が一段上がりました。私が実際に App Store 申請まで通したアプリで使った設計判断・プロンプト・修正パターンを、コードと共に体系化します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →