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-04中級

Rork Max × 折りたたみiPhone 2026 — フォルダブルデバイス時代に備えるアプリ設計戦略

Appleが2026年ロードマップに示す折りたたみiPhoneに向けたRork Maxでのアプリ設計戦略を解説。アダプティブレイアウト・マルチウィンドウ・SwiftUI対応など、今から準備すべき実践的な実装方法を紹介します。

rork-max41foldable-iphoneadaptive-layoutswiftui11multi-window202621

折りたたみ iPhone がやってくる — 開発者が今すぐ準備すべき理由

Apple の 2026 年製品ロードマップには、ついに「折りたたみ iPhone(Foldable iPhone)」が登場すると複数のサプライチェーン情報源が伝えています。Samsung Galaxy Z Fold シリーズや Google Pixel Fold が先行してきた折りたたみスマートフォン市場に、Apple がいよいよ参入するというのです。

折りたたみ iPhone の登場は、アプリ開発者にとって「チャンス」であり「リスク」でもあります。

チャンスの側面: 折りたたみ対応の高品質アプリは App Store で差別化できます。早期対応したアプリが「フィーチャードアプリ」として取り上げられる可能性も高い。

リスクの側面: 既存のレイアウト設計が折りたたみ状態(コンパクト画面)と展開状態(タブレット相当の大画面)の両方で正しく機能しない場合、低評価や離脱につながります。

Rork Max を使っている開発者は、今まさにこの準備を始める絶好の立場にいます。Rork Max が生成する SwiftUI ベースのコードは、アダプティブレイアウトへの対応がしやすく、Apple の新デバイスへの対応を他のツールより迅速に実現できる可能性があります。

折りたたみ iPhone の画面構成を理解する

Apple の折りたたみ iPhone は、現時点のリーク情報によると以下の構成が予想されています。

外側の画面(Cover Screen): 約 5.5 インチ相当のコンパクトディスプレイ。通常の iPhone のように片手操作が可能。

内側の画面(Main Screen / Fold Screen): 展開時に約 7.6〜8.0 インチ相当の大型ディスプレイ。iPad mini に近いサイズ感。

折り目(Crease): 中央に折り目があり、コンテンツが完全に平坦には表示されない(ただし Apple は品質改善に取り組んでいる)。

この「2段階のスクリーンサイズ」は、アプリが現在対応している iPhone(コンパクト)と iPad(大型)の中間的な位置づけです。しかし、重要なのはユーザーがリアルタイムでデバイスを折り曲げたり展開したりするという動的な変化への対応です。

Rork Max で折りたたみ対応レイアウトを設計する

SwiftUI の Adaptive Layout を活用する

Rork Max が生成する SwiftUI コードは、ジオメトリリーダーと環境変数を活用したアダプティブレイアウトに対応しています。

// Rork Max が生成するフォルダブル対応アダプティブレイアウトの基本実装
 
import SwiftUI
 
// デバイス状態を管理するViewModifier
struct AdaptiveFoldableLayout: ViewModifier {
    @Environment(\.horizontalSizeClass) private var horizontalSizeClass
    @Environment(\.verticalSizeClass) private var verticalSizeClass
    @State private var isFolded: Bool = false
 
    // 折りたたみ状態の検出
    // 実際の折りたたみiPhone対応はAppleのAPIリリース後に更新予定
    private var deviceState: DeviceState {
        switch (horizontalSizeClass, verticalSizeClass) {
        case (.compact, .regular):
            return .compactPhone  // 折りたたみ時(外側画面)または通常iPhone
        case (.regular, .regular):
            return .expandedFold  // 展開時(内側大画面)
        case (.regular, .compact):
            return .landscapePhone  // 横向き通常iPhone
        default:
            return .compactPhone
        }
    }
 
    func body(content: Content) -> some View {
        content
            .environment(\.deviceState, deviceState)
    }
}
 
// デバイス状態の定義
enum DeviceState {
    case compactPhone    // 折りたたみ時 / 通常iPhone
    case expandedFold   // フォルダブル展開時
    case landscapePhone // 横向きiPhone
}
 
// EnvironmentKey の定義
struct DeviceStateKey: EnvironmentKey {
    static let defaultValue: DeviceState = .compactPhone
}
 
extension EnvironmentValues {
    var deviceState: DeviceState {
        get { self[DeviceStateKey.self] }
        set { self[DeviceStateKey.self] = newValue }
    }
}
 
// 実際のアダプティブコンテンツビュー
struct AdaptiveMainView: View {
    @Environment(\.deviceState) private var deviceState
    @State private var selectedItem: ContentItem?
 
    var body: some View {
        GeometryReader { geometry in
            switch deviceState {
            case .expandedFold:
                // 展開時: マスター・ディテール レイアウト(iPad スタイル)
                HStack(spacing: 0) {
                    // 左ペイン: コンテンツリスト(全幅の 40%)
                    NavigationStack {
                        ContentListView(selection: $selectedItem)
                    }
                    .frame(width: geometry.size.width * 0.4)
                    .background(Color(.systemGroupedBackground))
 
                    Divider()
 
                    // 右ペイン: 詳細表示(残り 60%)
                    if let item = selectedItem {
                        ContentDetailView(item: item)
                            .frame(maxWidth: .infinity)
                    } else {
                        EmptyStateView()
                            .frame(maxWidth: .infinity)
                    }
                }
 
            case .compactPhone, .landscapePhone:
                // コンパクト時: 通常の NavigationStack
                NavigationStack {
                    ContentListView(selection: $selectedItem)
                        .navigationDestination(item: $selectedItem) { item in
                            ContentDetailView(item: item)
                        }
                }
            }
        }
        .modifier(AdaptiveFoldableLayout())
        .animation(.easeInOut(duration: 0.3), value: deviceState)  // 折り曲げ時のアニメーション
    }
}
 
// コンテンツリストビュー
struct ContentListView: View {
    @Binding var selection: ContentItem?
    @State private var items: [ContentItem] = ContentItem.sampleData
 
    var body: some View {
        List(items, selection: $selection) { item in
            ContentRowView(item: item)
                .listRowInsets(EdgeInsets(top: 8, leading: 16, bottom: 8, trailing: 16))
        }
        .listStyle(.insetGrouped)
        .navigationTitle("コンテンツ")
    }
}
 
// コンテンツ詳細ビュー
struct ContentDetailView: View {
    let item: ContentItem
    @Environment(\.deviceState) private var deviceState
 
    var body: some View {
        ScrollView {
            VStack(alignment: .leading, spacing: 16) {
                // 展開時は大きな画像・コンパクト時は小さな画像
                AsyncImage(url: item.imageURL) { image in
                    image
                        .resizable()
                        .aspectRatio(contentMode: .fill)
                } placeholder: {
                    Rectangle().fill(.quaternary)
                }
                .frame(height: deviceState == .expandedFold ? 300 : 200)
                .clipped()
                .cornerRadius(12)
 
                Text(item.title)
                    .font(deviceState == .expandedFold ? .title : .headline)
                    .fontWeight(.bold)
 
                Text(item.description)
                    .font(.body)
                    .foregroundStyle(.secondary)
            }
            .padding(deviceState == .expandedFold ? 24 : 16)
        }
        .navigationTitle(item.title)
        .navigationBarTitleDisplayMode(deviceState == .expandedFold ? .large : .inline)
    }
}
 
// ダミーデータ
struct ContentItem: Identifiable, Hashable {
    let id = UUID()
    let title: String
    let description: String
    let imageURL: URL?
 
    static let sampleData: [ContentItem] = [
        ContentItem(title: "サンプル記事 1", description: "説明テキスト", imageURL: nil),
        ContentItem(title: "サンプル記事 2", description: "説明テキスト", imageURL: nil),
    ]
}
 
struct ContentRowView: View {
    let item: ContentItem
 
    var body: some View {
        HStack(spacing: 12) {
            RoundedRectangle(cornerRadius: 8)
                .fill(.quaternary)
                .frame(width: 48, height: 48)
 
            VStack(alignment: .leading, spacing: 4) {
                Text(item.title)
                    .font(.headline)
                Text(item.description)
                    .font(.caption)
                    .foregroundStyle(.secondary)
                    .lineLimit(2)
            }
        }
    }
}
 
struct EmptyStateView: View {
    var body: some View {
        ContentUnavailableView(
            "アイテムを選択してください",
            systemImage: "doc.text",
            description: Text("左のリストからコンテンツを選んでください")
        )
    }
}

マルチウィンドウと Stage Manager 対応

折りたたみ iPhone では、展開時に iPad と同様の Stage Managerマルチウィンドウ 機能が利用できる可能性があります。Rork Max でこれに対応するには、アプリのシーン管理を適切に実装しておく点が肝心です。

// マルチウィンドウ対応の App エントリポイント
 
@main
struct FoldableReadyApp: App {
    var body: some Scene {
        // メインウィンドウ
        WindowGroup {
            AdaptiveMainView()
        }
 
        // 展開時に開ける詳細ウィンドウ(iPad / フォルダブル展開時)
        WindowGroup("詳細ビュー", id: "detail-view", for: ContentItem.ID.self) { $itemId in
            if let id = itemId, let item = ContentItem.sampleData.first(where: { $0.id == id }) {
                ContentDetailView(item: item)
                    .frame(minWidth: 400, minHeight: 500)
            }
        }
    }
}

Rork へのプロンプト例 — 折りたたみ対応アプリを作る

Rork Max に折りたたみ iPhone 対応アプリを作るよう指示する際の効果的なプロンプト例を紹介します。

ニュース読書アプリを作ってください。

以下の要件を満たしてください:
- iPhone 通常モード(コンパクト): リスト表示 → タップで記事詳細画面に遷移
- フォルダブルiPhone 展開モード(大画面): 左にリスト、右に記事詳細を並べて表示
- 画面サイズの変化に応じて、アニメーション付きでレイアウトが自動切替
- SwiftUI の horizontalSizeClass を使ってアダプティブレイアウトを実現
- 展開時は記事画像を大きく表示し、テキストを2カラムにする

データは JSONPlaceholder API(https://jsonplaceholder.typicode.com/posts)から取得してください。

今すぐ実装すべき5つの対策

1. ハードコードされたサイズ値を排除する frame(width: 375) のような固定値を使っているコードは折りたたみデバイスで崩れる原因になります。GeometryReader と相対サイズ(geometry.size.width * 0.5 など)に置き換えましょう。

2. horizontalSizeClass を使ったアダプティブ分岐を実装する コンパクト(通常 iPhone)と Regular(iPad・フォルダブル展開)で異なるレイアウトを提供する分岐を、今のうちに設計しておきましょう。

3. NavigationSplitView への移行を検討する iOS 16 以降で利用できる NavigationSplitView は、コンパクト時はシングルカラム、Regular 時はマスター・ディテール表示に自動切替します。折りたたみデバイスとの相性が最高です。

4. コンテンツの伸縮設計を優先する 固定高さのコンテナより、ScrollView + VStack を基本にした伸縮可能なレイアウトの方が、異なる画面サイズへの適応が容易です。

5. iPad シミュレータでの動作を今すぐ確認する 折りたたみ iPhone は 2026 年後半のリリースが予想されますが、iPad(Regular Size Class)での動作確認が折りたたみ展開モードのプレビューとして機能します。Xcode の iPad シミュレータで今すぐテストしましょう。

全体を振り返って

折りたたみ iPhone の登場は、2026 年のモバイルアプリ開発における最大のプラットフォーム変化の一つになる可能性があります。Rork Max の SwiftUI ベースのコード生成能力を活かし、今から horizontalSizeClass ベースのアダプティブレイアウトを設計・実装しておくことが、新デバイス登場時に最速でリリースできるための準備になります。

先手を打ったアプリは App Store のフィーチャード枠で有利になり、新デバイス購入者の注目を最初に集める機会を得られます。Rork Max と SwiftUI の力を借りて、折りたたみ iPhone 時代の先駆者になりましょう。

SwiftUI のアダプティブレイアウト設計についてさらに深く

シェア

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

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

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

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

関連記事

アプリ開発2026-07-03
Rork Max アプリに PDF の表示と書き出しを組み込む — PDFKit と ImageRenderer の使い分け
Rork Max のネイティブ Swift で PDFKit を使い、PDF の表示・検索・書き出しを実装します。UIGraphicsPDFRenderer と ImageRenderer の使い分け、パスワード保護、共有シート連携までの実装手順です。
アプリ開発2026-07-02
Rork Max のネイティブ Swift で MusicKit を使う — Apple Music の認可・検索・再生を最小構成で通す
Rork Max で生成した Swift アプリに MusicKit を組み込む手順。MusicAuthorization の認可、MusicCatalogSearchRequest での検索、ApplicationMusicPlayer と SystemMusicPlayer の使い分け、未加入ユーザーへのオファー表示までを実装コードで解説します。
開発ツール2026-05-25
Rork で作る iOS アプリに StoreKit 2 で買い切り課金を実装するノート
Rork が生成する Swift / SwiftUI コードに StoreKit 2 で買い切り課金を後付け実装する手順メモ。累計 5,000 万 DL の壁紙アプリで StoreKit 1 から 2 へ移行した経験を踏まえて、ProductID 設計・Transaction 検証・Paywall UI・本番ハマりどころまで実装サンプル込みで共有します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →