重要ポイント
View ProtocolはSwiftUIの中心的なプロトコルです。必要なプロパティは1つだけ:var body: some View。bodyはUIの記述を返すcomputedプロパティです。SwiftUIは状態が変わるたびにbodyを呼び出し、GPUで結果をレンダリングします。
@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()を使用したカスタム修飾子。
// @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)
}
}
}NavigationStack (iOS 16+) — データ駆動ナビゲーション。パス(ハッシュ可能な値の配列)を受け取り、navigationDestinationで遷移先を表示します。遷移先ビュー付きのNavigationLinkを置き換えます。NavigationLink — スタックをナビゲートするボタン。List — セクション、スワイプ、削除、ドラッグ&ドロップをサポートする垂直リスト。Form — 設定用に特化したList:セクション、ピッカー、トグル、テキストフィールド。Section — ヘッダーとフッター付きのList/Formでのグループ化。ViewModifier — スタイルを再利用するためのカスタム修飾子。.modifier(CustomModifier()) — 適用。
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に合わせてスケーリングする適応型サイズ。
Property WrappersはSwiftUIにおける状態管理の基盤です。@State — ローカル状態(値型)。@Binding — 親の状態との接続。@StateObject — ObservableObjectを作成。SwiftUIがオブジェクトのライフサイクルを管理。@ObservedObject — 外部のObservableObjectを監視。@EnvironmentObject — 環境からのオブジェクト(.environmentObject()による依存性注入)。@Environment — システム値(.colorScheme、.locale)。@AppStorage — UserDefaults。@FetchRequest — Core Dataクエリ。@FocusState — 入力フォーカス。
| ラッパー | 目的 | 所有 |
|---|---|---|
| @State | ローカル状態(値型) | Viewが所有 |
| @Binding | 親状態との接続 | 親が所有 |
| @StateObject | ObservableObjectを作成 | Viewが所有 |
| @ObservedObject | 外部オブジェクトを監視 | 外部の所有者 |
| @EnvironmentObject | 環境からのオブジェクト | 祖先が所有 |
| @Environment | システム値 | システム |
| @AppStorage | UserDefaults | UserDefaults |
| @FocusState | 入力フォーカス | Viewが所有 |
@StateObject vs @ObservedObject:@StateObjectはオブジェクトを作成し、@ObservedObjectはそれを監視します。階層内での最初のモデル作成には@StateObjectを、子ビューへの受け渡しには@ObservedObjectを使用します。@FocusState — フォーカス管理:.focused($field, equals: .email)。複数フィールドにenumをサポート。
@Environment — システム値:colorScheme、locale、sizeCategory、layoutDirection、managedObjectContext。カスタム環境値(Custom Environment Values) — EnvironmentKeyによるカスタム値。依存性注入に使用:明示的なパラメータなしでサービスを渡す。.environment()修飾子 — 階層内に値を設定。@EnvironmentObject — .environmentObject()からのObservableObject。参照型を渡す点で@Environmentと異なります。IT Sectrはシステム値には@Environment、サービスには@EnvironmentObjectを推奨します。
.task{} — ビュー表示時の非同期操作。非表示時に自動キャンセル。async/await用に.onAppearを置き換え。.onAppear{} — 表示時の同期操作。.onDisappear{} — 非表示時の操作。.onChange(of:) — 値変更への反応。.onReceive(Publisher) — Combineパブリッシャーへの反応。SwiftUIにおけるViewのライフサイクル:init → onAppear → body(レンダリング)→ onDisappear。状態変化時:body → diff → 再レンダリング。IT Sectrは非同期読み込みには.task、アナリティクスには.onAppearを推奨します。
.animation() — アニメーション修飾子。.transition() — 表示/非表示アニメーション。withAnimation — 明示的な状態変更アニメーション。matchedGeometryEffect — 異なるView間のアニメーション(ヒーローアニメーション)。PhaseAnimator (iOS 17+) — enumベースの多相アニメーション。KeyframeAnimator (iOS 17+) — キーフレームを使ったフレーム単位のアニメーション。SwiftUIアニメーションはCore Animationを介してGPU上で実行されます。IT Sectrは自然なアニメーションには.spring()、物理効果には.interpolatingSpringを推奨します。
ObservableObject — @Publishedプロパティを持つオブジェクトのプロトコル。SwiftUIはobjectWillChangeパブリッシャーを購読。@Published — プロパティ変更を公開。@StateObject — ObservableObjectを作成、ライフサイクルを管理。@ObservedObject — 外部を監視。Combine — リアクティブプログラミングのフレームワーク。@EnvironmentObject — 環境を介したDI。.environmentObject()で設定、@EnvironmentObjectで読み取り。MVVM — 標準アーキテクチャ:View(SwiftUI)— ViewModel(ObservableObject)— Model。IT Sectrは主要なViewModelにMVVM + @StateObjectを推奨します。
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はすべてのインタラクティブ要素にアクセシビリティラベルを推奨します。
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 (iOS 16+) — チャート構築のためのフレームワーク。Chart { } — 基本コンテナ。BarMark、LineMark、PointMark、AreaMark、RuleMark — マーク。データにはForEach。ChartAxis — 軸のカスタマイズ。.chartXAxis、.chartYAxis。ChartLegend — 凡例。補間 — catmullRom、linear、step。アニメーション — Chart用.animation()。IT Sectrは組み込みチャートにはSwift Charts、複雑なチャートにはCharts(DGCharts)を推奨します。
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を完全に置き換えます。
よくある質問
View Protocolは基本プロトコル。var body: some Viewが必要。bodyはGPUでレンダリングされるUIの記述。
@ViewBuilderは複数のView用のResult Builder。コンテナ内でif/else、switch、ForEachを可能にします。
@StateObjectはオブジェクトを作成。@ObservedObjectは既存のものを監視。階層での最初の作成には@StateObject。
NavigationStack — データ駆動ナビゲーション。パスベース、ディープリンク。NavigationViewを置き換え。
@FocusState — 入力フォーカス管理。.focused()修飾子。複数フィールドにenumをサポート。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。