「
EntryPane().tabItem { Label("記入", systemImage: "square.and.pencil") }を、見た瞬間に分解して理解できる自分へ」
このガイドは、Swift/SwiftUI のコードを “品詞分解” する感覚を身につけるための、実務直結のチートシート+サンプル大全です。型(構造体)、関数/メソッド、プロパティ、モディファイア、クロージャ、トレーリングクロージャ、some View、extension View、ViewModifier まで、一気に腹落ちさせます。
目次
- ぱっと見で判別!チートシート
- Swift 基礎:型/構造体/関数/プロパティ/イニシャライザ
- クロージャ&関数型&引数ラベル&トレーリングクロージャ
- SwiftUI の正体:View と「モディファイア=Viewを返すメソッド」
tabItemとLabelを完全分解applyTwice/calc/framedSquareの完全分解- 実行用ミニデモ(コピペOK)
- 10本ノック:即時判別ドリル(解答付き)
- 実務で効く“見極めコツ”
- 用語ミニ辞典(必要最小限を濃く)
- 次の一歩
1) ぱっと見で判別!チートシート
- 構造体(struct):
struct Name { ... }で宣言。型名は大文字始まり。初期化はName(...)。 - メソッド(method):型の中の
func name(...)。小文字始まり。呼び出しはinstance.name(...)。 - プロパティ:
var/let。計算型は{ ... }を持つ。 - モディファイア(modifier):
extension Viewに定義された “View を返すメソッド”。見た目上はview.modifierName(...)の ドット連結。 - イニシャライザ(init):
init(...)/TypeName(...)。 - クロージャ:
{ ... }。最後の引数がクロージャなら trailing closure で()の外に{ }を置ける。 - 大文字/小文字ルール:型・プロトコルは大文字/値・関数は小文字。まずはこれで8割判別。
2) Swift 基礎:型/構造体/関数/プロパティ/イニシャライザ
2.1 構造体+プロトコル+イニシャライザ
protocol Greetable {
func greet() -> String
}
struct Person: Greetable { // 構造体(型名は大文字)
let name: String // ストアドプロパティ
init(name: String) { // イニシャライザ
self.name = name
}
func greet() -> String { // メソッド(小文字始まり)
"Hello, \(name)"
}
}
let p = Person(name: "Taro") // 構造体の初期化(TypeName(...))
print(p.greet()) // メソッド呼び出し
2.2 extension と “既存型へメソッド追加”
extension String {
func boxed() -> String { // 既存型 String にメソッド追加
"[\(self)]"
}
}
"hi".boxed() // => "[hi]"
2.3 計算型プロパティ vs メソッド
struct Rect {
var width: Double
var height: Double
var area: Double { // 計算型プロパティ(()で呼ばない)
width * height
}
func area() -> Double { // メソッド(()が必要)
width * height
}
}
指針:**“値そのもの”ならプロパティ、“処理”**を強調したいならメソッド。
3) クロージャ&関数型&引数ラベル&トレーリングクロージャ
3.1 applyTwice を一文字ずつ分解
func applyTwice(_ f: (Int) -> Int, to x: Int) -> Int { f(f(x)) }
func:関数宣言。applyTwice:関数名。(_ f: (Int) -> Int, to x: Int):2引数。_ f: (Int) -> Int:外部名なし_/内部名f/関数型(Int→Int)を値として受け取る。to x: Int:外部名to/内部名x/型Int。
-> Int:戻り値はInt。- 本体
{ f(f(x)) }:xにfを適用 → さらにfを適用。
💲 💲 $0 の意味(自動引数名)
の意味(自動引数名)
$0 の意味(自動引数名)クロージャの引数名を省略すると、最初の引数は $0、2番めは $1 … で参照できます。
let doubled = applyTwice({ $0 * 2 }, to: 3)
// 1回目: { $0 * 2 }(3) == 6
// 2回目: { $0 * 2 }(6) == 12 → doubled == 12
3.2 calc と trailing closure
func calc(_ x: Int, operation: (Int) -> Int) -> Int { operation(x) }
let y = calc(10) { v in v + 5 } // trailing closure(最後の引数がクロージャ)
// 等価: calc(10, operation: { v in v + 5 })
合図:最後の引数がクロージャなら
{ ... }を()の外へ出せる。
4) SwiftUI の正体:View と「モディファイア=Viewを返すメソッド」
4.1 モディファイアは“ただのメソッド”
extension View {
func framedSquare(_ size: CGFloat) -> some View { // 自作モディファイア相当
self
.frame(width: size, height: size) // Viewメソッド(モディファイア)
.border(.secondary) // 同上:新しい View を返す
}
}
Text("Hi").framedSquare(80)
- モディファイアの正体=
extension Viewに定義された “View を返すメソッド”。 - 連結は メソッドチェーン。毎回 新しい View を返す(元の View は不変)。
some Viewは Opaque Result Type。複雑化した具体型を呼び出し側から隠す。
4.2 ViewModifier パターン
struct Badge: ViewModifier {
func body(content: Content) -> some View {
content
.padding(8)
.overlay(alignment: .topTrailing) {
Circle().frame(width: 8, height: 8)
}
}
}
extension View {
func badgeDot() -> some View { modifier(Badge()) }
}
Image(systemName: "bell").badgeDot()
modifier(_:)もViewのメソッド。メソッド=モディファイアという感覚でOK。
5) tabItem と Label を完全分解
TabView {
EntryPane() // 構造体の初期化(some View)
.tabItem { // View拡張メソッド(モディファイア)
Label("記入", systemImage: "square.and.pencil") // Label構造体の初期化
}
Text("日記")
.tabItem {
Label("日記", systemImage: "book.closed")
}
}
EntryPane():型EntryPaneのイニシャライザ。.tabItem { ... }:Viewに生えたメソッド=モディファイア。{ Label(...) }:クロージャ(戻り値はLabel構造体のインスタンス)。
6) 完全分解 3 連発
6.1 applyTwice
func applyTwice(_ f: (Int) -> Int, to x: Int) -> Int { f(f(x)) }
// func …… 関数宣言
// applyTwice …… 関数名
// (_ f: (Int) -> Int, to x: Int) …… 2引数(外部名の有無と型を注視)
// -> Int …… 戻り値の型
// { f(f(x)) } …… 本体(x に f を2回適用)
6.2 calc & trailing closure
func calc(_ x: Int, operation: (Int) -> Int) -> Int { operation(x) }
let y = calc(10) { v in v + 5 }
// 最後の引数がクロージャ → () の外に { } を出せる
// 等価: calc(10, operation: { v in v + 5 })
6.3 自作モディファイア framedSquare
extension View {
func framedSquare(_ size: CGFloat) -> some View {
self // レシーバ(元の View)
.frame(width: size, height: size) // Viewメソッド(モディファイア)
.border(.secondary) // さらにモディファイア
}
}
_ size:外部名なしで呼べる(view.framedSquare(80))。CGFloat:UI座標/サイズで使う実数型。some View:具体型を隠す。
7) 実行用ミニデモ(コピペOK)
import SwiftUI
// ① 関数とクロージャ(基礎)
func applyTwice(_ f: (Int) -> Int, to x: Int) -> Int { f(f(x)) }
func calc(_ x: Int, operation: (Int) -> Int) -> Int { operation(x) }
// ② View拡張(自作モディファイア)
extension View {
func framedSquare(_ size: CGFloat) -> some View {
self
.frame(width: size, height: size)
.border(.secondary)
}
}
struct DemoView: View {
var body: some View {
VStack(spacing: 16) {
Text("applyTwice → \(applyTwice({ $0 * 2 }, to: 3))") // 12
Text("calc → \(calc(10) { $0 + 5 })") // 15
Text("Hi").framedSquare(80) // 自作モディファイア
}
.padding()
}
}
#Preview { DemoView() }
8) 10本ノック:即時判別ドリル(解答付き)
Q1
struct Chip: View { // ?
var text: String // ?
var body: some View { // ?
Text(text) // ?
.padding(.horizontal, 10) // ?
.padding(.vertical, 6) // ?
.background(.thinMaterial) // ?
.clipShape(Capsule()) // ?
}
}
Q2
extension View { // ?
func capsuleBackground() -> some View { // ?
self
.padding(8) // ?
.background(.ultraThinMaterial) // ?
.clipShape(Capsule()) // ?
}
}
Text("Hi").capsuleBackground() // ?
Q3
func makeLabel(_ title: String, systemImage: String) -> some View { // ?
Label(title, systemImage: systemImage) // ?
}
TabView {
Text("Home")
.tabItem { makeLabel("ホーム", systemImage: "house") } // ?(2つ)
}
解答
- Q1: 構造体 / ストアドプロパティ / 計算型プロパティ /
Textのイニシャライザ / モディファイア / モディファイア / モディファイア /Capsuleのイニシャライザ(モディファイア引数) - Q2: extension / メソッド(View返す→モディファイア相当) / モディファイア / モディファイア /
Capsuleイニシャライザ(モディファイア引数) / メソッド呼び出し(=モディファイア適用) - Q3: 関数 /
Labelイニシャライザ /.tabItemはモディファイア、makeLabel(...)は関数呼び出し(中身はLabelを返すクロージャ)
9) 実務で効く“見極めコツ”
- 大文字は型/小文字は値・関数。
TypeName(...)はイニシャライザ。 - ドット連鎖の小文字はだいたいメソッド。SwiftUI なら ほぼモディファイア。
{ ... }を見たらクロージャを疑う。最後の引数なら trailing closure かも。- “値っぽいか/動作っぽいか” でプロパティとメソッドを仕分け。
- Option-Click(⌥クリック)で宣言確認。
structかfuncかinitか一撃で分かる。
10) 用語ミニ辞典
- 外部引数名/内部引数名:
func f(ex external: Type)。呼び出しはex:、中ではexternal。 - 関数型
(A,B)->C:関数という“値”の型。クロージャはこの型のインスタンス。 - クロージャ:無名関数。
{ (x: Int) -> Int in x + 1 }/省略で{ $0 + 1 }。 - trailing closure:最後の引数がクロージャの時、
()の外に{}を置ける。 some View:Opaque Result Type。具体型を隠して「ある View」とだけ約束。CGFloat:UI座標/サイズで使う浮動小数点。- モディファイア:
Viewに生えたメソッド。毎回新しい View を返す(関数型スタイル)。

コメント