モバイル開発におけるSwiftUI:概要、主要概念、仕組み

著者: IT Sectr 公開日: 2026-07-02 読了時間: 10 分
SwiftUIは、Appleが提供する宣言的フレームワークで、すべてのプラットフォームでインターフェースを構築できます。Apple SwiftUI Docs (2025)によると、App Storeの新しいアプリの70%がSwiftUIを使用しています。SwiftUIの主要概念(View Protocol、@ViewBuilder、NavigationStack)を理解することが、現代のiOS開発の基盤です。

重要ポイント

  • View Protocol — var body: some View。各ViewはViewプロトコルに準拠する構造体。bodyはUIの記述。
  • @ViewBuilder — コンテナ内で複数のViewを記述するためのResult Builder。body内でif/else、switch、ForEach。
  • NavigationStack (iOS 16+) — データ駆動ナビゲーション。パスベース、ディープリンク。NavigationViewの後継。
  • @StateObject — オブジェクトの所有。@ObservedObject — 観測。@EnvironmentObject — 環境。
  • @FocusState — フォーカス管理。.task{}、.onAppear{} — ライフサイクル。PreviewProvider — プレビュー。

基礎(View Protocol、body、some View、@ViewBuilder)

View ProtocolはSwiftUIの中心的なプロトコルです。必要なプロパティは1つだけ:var body: some View。bodyはUIの記述を返すcomputedプロパティです。SwiftUIは状態が変わるたびにbodyを呼び出し、GPUで結果をレンダリングします。

@ViewBuilder

@ViewBuilderはViewのResult Builderです。returnやTupleViewなしでクロージャ内に複数のViewを記述できます。if/else、switch、ForEachをサポートしています。すべてのコンテナ(VStack、HStack、ZStack、Group)は@ViewBuilderを使用します。レイアウトなしでグループ化するにはGroup { … }を使用します。some ViewはOpaque Typeです。コンパイラは具体的なViewタイプ(Text、Button、VStackなど)を認識していますが、外部からはsome Viewとして返されます。これにより、シグネチャを変更せずにbodyのタイプを変更できます。ViewModifier — View修飾子:.font()、.padding()、.background()。ViewModifierプロトコルと.modifier()を使用したカスタム修飾子。

swift
// @ViewBuilderとNavigationStackを使用したViewの例
struct ContentView: View {
    @State private var items = ["Item 1", "Item 2"]

    var body: some View {
        NavigationStack {
            List(items, id: .self) { item in
                NavigationLink(item) {
                    DetailView(item: item)
                }
            }
            .navigationTitle("Items")
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button("Add") {
                        items.append("New Item")
                    }
                }
            }
        }
    }
}

// @StateObjectを使用したDetailView
struct DetailView: View {
    let item: String
    @StateObject private var viewModel = DetailViewModel()

    var body: some View {
        Text(item)
            .task {
                await viewModel.loadDetails(for: item)
            }
    }
}

修飾子とコンテナ(ViewModifier、NavigationStack、List、Form)

NavigationStack (iOS 16+) — データ駆動ナビゲーション。パス(ハッシュ可能な値の配列)を受け取り、navigationDestinationで遷移先を表示します。遷移先ビュー付きのNavigationLinkを置き換えます。NavigationLink — スタックをナビゲートするボタン。List — セクション、スワイプ、削除、ドラッグ&ドロップをサポートする垂直リスト。Form — 設定用に特化したList:セクション、ピッカー、トグル、テキストフィールド。Section — ヘッダーとフッター付きのList/Formでのグループ化。ViewModifier — スタイルを再利用するためのカスタム修飾子。.modifier(CustomModifier()) — 適用。

ListとFormの詳細

ListはSwiftUIにおけるUITableViewに相当します。.onDelete、.onMove、.refreshableをサポート。SwipeActions — .swipeActions { Button("削除", role: .destructive) { } }。Form — 設定用に最適化:DatePicker、Toggle、Stepper、Picker。ヘッダー/フッター付きのSection — グループ化用。OutlineGroup — 階層リスト(セクション付きUITableViewに相当)。DisclosureGroup — 折りたたみ可能なセクション。IT SectrはデータにはList、設定にはFormを推奨します。

PreviewProvider — Xcode Canvasでプレビューするためのプロトコル。Canvas — インタラクティブなSwiftUIプレビュー(@mainとSwift 5.9+が必要)。@ScaledMetric — Dynamic Typeに合わせてスケーリングする適応型サイズ。

状態管理(@StateObject、@ObservedObject、@EnvironmentObject、@FocusState)

Property WrappersはSwiftUIにおける状態管理の基盤です。@State — ローカル状態(値型)。@Binding — 親の状態との接続。@StateObject — ObservableObjectを作成。SwiftUIがオブジェクトのライフサイクルを管理。@ObservedObject — 外部のObservableObjectを監視。@EnvironmentObject — 環境からのオブジェクト(.environmentObject()による依存性注入)。@Environment — システム値(.colorScheme、.locale)。@AppStorage — UserDefaults。@FetchRequest — Core Dataクエリ。@FocusState — 入力フォーカス。

ラッパー 目的 所有
@Stateローカル状態(値型)Viewが所有
@Binding親状態との接続親が所有
@StateObjectObservableObjectを作成Viewが所有
@ObservedObject外部オブジェクトを監視外部の所有者
@EnvironmentObject環境からのオブジェクト祖先が所有
@Environmentシステム値システム
@AppStorageUserDefaultsUserDefaults
@FocusState入力フォーカスViewが所有

@StateObject vs @ObservedObject:@StateObjectはオブジェクトを作成し、@ObservedObjectはそれを監視します。階層内での最初のモデル作成には@StateObjectを、子ビューへの受け渡しには@ObservedObjectを使用します。@FocusState — フォーカス管理:.focused($field, equals: .email)。複数フィールドにenumをサポート。

環境値とDI

@Environment — システム値:colorScheme、locale、sizeCategory、layoutDirection、managedObjectContext。カスタム環境値(Custom Environment Values) — EnvironmentKeyによるカスタム値。依存性注入に使用:明示的なパラメータなしでサービスを渡す。.environment()修飾子 — 階層内に値を設定。@EnvironmentObject — .environmentObject()からのObservableObject。参照型を渡す点で@Environmentと異なります。IT Sectrはシステム値には@Environment、サービスには@EnvironmentObjectを推奨します。

ライフサイクル(.task、.onAppear、.onDisappear)

.task{} — ビュー表示時の非同期操作。非表示時に自動キャンセル。async/await用に.onAppearを置き換え。.onAppear{} — 表示時の同期操作。.onDisappear{} — 非表示時の操作。.onChange(of:) — 値変更への反応。.onReceive(Publisher) — Combineパブリッシャーへの反応。SwiftUIにおけるViewのライフサイクル:init → onAppear → body(レンダリング)→ onDisappear。状態変化時:body → diff → 再レンダリング。IT Sectrは非同期読み込みには.task、アナリティクスには.onAppearを推奨します。

SwiftUIのアニメーション

.animation() — アニメーション修飾子。.transition() — 表示/非表示アニメーション。withAnimation — 明示的な状態変更アニメーション。matchedGeometryEffect — 異なるView間のアニメーション(ヒーローアニメーション)。PhaseAnimator (iOS 17+) — enumベースの多相アニメーション。KeyframeAnimator (iOS 17+) — キーフレームを使ったフレーム単位のアニメーション。SwiftUIアニメーションはCore Animationを介してGPU上で実行されます。IT Sectrは自然なアニメーションには.spring()、物理効果には.interpolatingSpringを推奨します。

データフロー(Bindings、@Published、ObservableObject)

ObservableObject — @Publishedプロパティを持つオブジェクトのプロトコル。SwiftUIはobjectWillChangeパブリッシャーを購読。@Published — プロパティ変更を公開。@StateObject — ObservableObjectを作成、ライフサイクルを管理。@ObservedObject — 外部を監視。Combine — リアクティブプログラミングのフレームワーク。@EnvironmentObject — 環境を介したDI。.environmentObject()で設定、@EnvironmentObjectで読み取り。MVVM — 標準アーキテクチャ:View(SwiftUI)— ViewModel(ObservableObject)— Model。IT Sectrは主要なViewModelにMVVM + @StateObjectを推奨します。

swift
class UserViewModel: ObservableObject {
    @Published var users: [User] = []
    @Published var isLoading = false

    func loadUsers() async {
        isLoading = true
        defer { isLoading = false }
        do {
            users = try await api.fetchUsers()
        } catch {
            print("エラー: \(error)")
        }
    }
}

struct UsersView: View {
    @StateObject private var viewModel = UserViewModel()

    var body: some View {
        List(viewModel.users, id: \.id) { user in
            Text(user.name)
        }
        .task { await viewModel.loadUsers() }
        .overlay {
            if viewModel.isLoading { ProgressView() }
        }
    }
}

アクセシビリティとローカライゼーション

アクセシビリティ in SwiftUI:.accessibilityLabel()、.accessibilityHint()、.accessibilityValue()、.accessibilityAddTraits()。VoiceOverがアクセシビリティラベルを読み上げ。Dynamic Type — @ScaledMetric、@DynamicProperty。ローカライゼーション:String(localized:)(SwiftUI + String Catalog)。LocalizedStringKey — 自動翻訳。複数形ルール — String Catalog経由(one、few、many、other)。右から左(アラビア語、ヘブライ語)— 自動サポート。.environment(.layoutDirection, .rightToLeft)。IT Sectrはすべてのインタラクティブ要素にアクセシビリティラベルを推奨します。

swift
struct AccessibleButton: View {
    let action: () -> Void

    var body: some View {
        Button(action: action) {
            Label("Settings", systemImage: "gear")
        }
        .accessibilityLabel("Open Settings")
        .accessibilityHint("Double tap to navigate to settings screen")
        .accessibilityAddTraits(.isButton)
    }
}

// Dynamic Typeのサポート
struct ScalableText: View {
    @ScaledMetric private var fontSize: CGFloat = 17

    var body: some View {
        Text("Hello, World!")
            .font(.system(size: fontSize))
    }
}

チャートと可視化(Swift Charts)

Swift Charts (iOS 16+) — チャート構築のためのフレームワーク。Chart { } — 基本コンテナ。BarMark、LineMark、PointMark、AreaMark、RuleMark — マーク。データにはForEach。ChartAxis — 軸のカスタマイズ。.chartXAxis、.chartYAxis。ChartLegend — 凡例。補間 — catmullRom、linear、step。アニメーション — Chart用.animation()。IT Sectrは組み込みチャートにはSwift Charts、複雑なチャートにはCharts(DGCharts)を推奨します。

swift
import Charts

struct MonthlySales: Identifiable {
    let id = UUID()
    let month: String
    let sales: Double
}

struct SalesChart: View {
    let data: [MonthlySales]

    var body: some View {
        Chart(data) { item in
            BarMark(
                x: .value("Month", item.month),
                y: .value("Sales", item.sales)
            )
            .foregroundStyle(.blue.gradient)
        }
        .chartXAxisLabel("Month")
        .chartYAxisLabel("Sales")
        .frame(height: 200)
        .padding()
    }
}

Swift Package Manager (SPM) — Appleの依存関係マネージャー。Xcodeに統合。サポート:バイナリパッケージ、リソース、テスト、swift-6 strict concurrency。semverタグでGitHub経由のパッケージ公開。SPMはCocoaPodsとCarthageに代わるSwift依存関係の事実上の標準です。IT Sectrはすべての新規プロジェクトにSPMを推奨します。

Swift Concurrency (async/await、TaskGroup、AsyncSequence) — async/awaitはSwift 5.5+に組み込み。Task — 非同期の単位。TaskGroup — 並列タスク。AsyncSequence — 非同期シーケンス(AsyncStream、AsyncAlgorithms)。Task Local Values — Taskのコンテキストデータ。Swift Concurrencyは非同期操作においてCombineを完全に置き換えます。

よくある質問

SwiftUIのView Protocolとは?

View Protocolは基本プロトコル。var body: some Viewが必要。bodyはGPUでレンダリングされるUIの記述。

@ViewBuilderとは何か、なぜ必要か?

@ViewBuilderは複数のView用のResult Builder。コンテナ内でif/else、switch、ForEachを可能にします。

@StateObjectと@ObservedObjectの違いは?

@StateObjectはオブジェクトを作成。@ObservedObjectは既存のものを監視。階層での最初の作成には@StateObject。

iOS 16+のNavigationStackとは?

NavigationStack — データ駆動ナビゲーション。パスベース、ディープリンク。NavigationViewを置き換え。

SwiftUIで@FocusStateはどのように動作するか?

@FocusState — 入力フォーカス管理。.focused()修飾子。複数フィールドにenumをサポート。

まとめ

  • View Protocol — var body: some View。SwiftUIの基礎。各Viewは構造体。
  • @ViewBuilder — 複数Viewの宣言的構文。body内でif/else、ForEach。
  • NavigationStack (iOS 16+) — 最新ナビゲーション。データ駆動、パスベース。
  • @StateObject — モデル所有。@ObservedObject — 監視。@EnvironmentObject — DI。
  • @FocusState — フォーカス管理。フォームや複数入力フィールドに便利。
  • .task{} — 自動キャンセル付き非同期操作。.onAppear{} — 同期。
  • PreviewProviderとCanvas — Xcodeでプレビュー。@ScaledMetric — 適応型サイズ。

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談