SwiftUIで直感的に組むUIレイアウト:Auto Layoutの呪縛から解き放たれた日の話

目次

「赤い線」に怯えていたあの頃

10年ほど前、私がまだ駆け出しのiOSエンジニアとして現場を走り回っていた頃の話です。
当時のアプリ開発といえば、XcodeのInterface Builder(Storyboard)とにらめっこするのが日常でした。画面上のパーツをマウスでドラッグし、位置を決める。一見すると直感的で簡単そうに見えるあの作業。

でも、そこには「Auto Layout」という魔物が潜んでいました。

「このボタンは右端から20pt、上から100ptの位置に固定。ただし画面サイズが変わったら横幅いっぱいに広げること。あ、高さは固定で」

こうしたルール(制約)を一つ一つ手動で設定していくんですが、これがもう、パズルなんて生易しいものではありませんでした。一つでも設定が矛盾すると、画面には警告を示す不吉な「赤い線」が表示され、実行するとレイアウトが盛大に崩壊する。
iPhoneの画面サイズの種類が増えるたびに、この制約地獄は複雑さを増していきました。深夜のオフィスで、真っ赤になったStoryboardを見つめながら、「もうアプリ開発なんて辞めたい」と頭を抱えた夜は一度や二度じゃありません。

そんな私を、そして世界中のiOSエンジニアを救ってくれたのが、2019年に登場した「SwiftUI」でした。

衝撃でした。
VStack { Text("Hello") }
たったこれだけのコードを書いた瞬間、プレビュー画面の中央に文字が表示されたんです。座標計算も、制約のコンフリクトも、あの忌まわしい赤い線もない。
まるでレゴブロックを積み上げるように、コードでUIを記述していく感覚。直感的で、速くて、何より「楽しい」。

「これなら、個人の副業でも爆速でアプリが作れる」

直感的にそう確信しました。
実際、今の副業市場やフリーランス案件を見てみると、SwiftUIのスキルは必須になりつつあります。新規開発案件の多くがSwiftUI採用に舵を切っていて、開発スピードは従来のUIKit時代の2倍、いや3倍と言っても過言じゃありません。

今回は、かつてAuto Layoutに泣かされ続けた私が、SwiftUIという最強の武器を使ってどうやって思い通りのレイアウトを組んでいるのか。その思考法と、現場で生き残るためのテクニックを共有します。教科書的な機能説明ではなく、泥臭い現場の失敗談も交えて話していくので、肩の力を抜いて読んでみてください。

深夜のオフィスで、以前のXcodeのStoryboard画面に出てくる大量のエラー(赤い線)に頭を抱えているが、現在のSwiftUIのシンプルなコード画面を見て救われたような表情をしている30代男性エンジニアの線画イラスト

なぜSwiftUIが副業エンジニアの武器になるのか

技術的な書き方の前に、なぜ私がこれほどまでにSwiftUIを推すのか。その理由は「稼ぐ」という視点で見ると明らかです。

かつての命令的UI(UIKit)は、「ボタンを置いて、背景を赤にして、文字を入れて…」と手順を指示するスタイルでした。
対してSwiftUIは宣言的UI。「赤い背景で文字が入ったボタンがある」という状態(あるべき姿)を記述します。

これが何を意味するかというと、「コードを読めば、どんな画面かわかる」ということです。
久しぶりに自分のコードを見返した時や、副業で他人のコードを引き継いだ時の理解スピードが段違いなんです。副業案件では、限られた時間で成果を出すことが求められますから、メンテナンス性が高いコードはそれだけで自分の首を救ってくれます。

それに、Xcodeのプレビュー機能(Canvas)。これがもう、強力すぎます。
コードを書き換えた瞬間に、右側の画面に変更が反映される。いちいちビルドしてシミュレーターを起動して…というあの待ち時間がゼロになるんです。
「ここの余白、あと2ピクセル広げたいな」
この微調整を、クライアントとZoomで画面共有しながらその場で完了できる。このライブ感は、信頼獲得において最強の武器になります。

脳みそを「座標」から「積み木」に切り替える

SwiftUIでレイアウトをする際、一番大事なのは「考え方」の転換です。
座標(X, Y)で考えるのをやめてください。「左から何ピクセル」とか、そういうのは忘れましょう。
代わりに「積み木」で考えるんです。

たった3つのコンテナで世界は作れる

SwiftUIのレイアウトは、基本的に以下の3つのコンテナ(入れ物)の組み合わせだけで作れます。これだけで世界の9割のUIは再現可能だと言い切れます。

  1. VStack (Vertical Stack): 縦に積む
  2. HStack (Horizontal Stack): 横に並べる
  3. ZStack (Depth Stack): 奥行き方向に重ねる(手前と奥)

例えば、Instagramの投稿画面を思い浮かべてみてください。
ユーザーアイコンとユーザー名は「横」に並んでいますよね? これは HStack です。
その下に写真、さらにその下に「いいね」ボタン群がある。これは VStack です。
写真の右上に「1/3」みたいな枚数表示が重なっているなら、それは ZStack です。

作りたい画面を見た瞬間、「ここはHStackの中にVStackが入って…」と脳内で分解できるようになれば、もう勝ったも同然です。

// シンプルなプロフィールの例
VStack {
    Image("user_icon")
    Text("ユーザー名")
    HStack {
        Button("フォロー") {}
        Button("メッセージ") {}
    }
}

この「入れ子構造」を直感的に書けるのがSwiftUIの凄さ。HTML/CSSで苦労して配置していたのが嘘のように簡単になります。

カフェでノートにアプリのUIスケッチを描きながら、それを「VStack」「HStack」といったブロックの積み重ねとして脳内で分解・構造化しているエンジニアの線画イラスト

「Modifierの順序」という初心者が必ずハマる罠

コンテナの次に重要なのが、Modifier(修飾子)です。
.padding(), .background(), .cornerRadius() など、Viewに対して「装飾」を施すメソッドたち。

ここで初心者が必ずハマる、そして私も現場で何度も「あれ?おかしいな」と頭をひねった落とし穴があります。
それは、「Modifierを書く順番で、結果が全く変わる」ということです。

これを理解するには、「額縁」をイメージすると分かりやすいかもしれません。
SwiftUIのViewは、Modifierを適用するたびに、新しいView(額縁)に包まれていくんです。

ちょっと実験してみましょう。

パターンA:

Text("Hello")
    .background(Color.red) // ①背景を赤くする
    .padding()             // ②余白をつける

この場合、「Hello」という文字の背景が赤くなり、その外側に余白ができます。つまり、赤い四角の外に透明なスペースができる状態です。

パターンB:

Text("Hello")
    .padding()             // ①余白をつける
    .background(Color.red) // ②背景を赤くする

この場合、まず「Hello」の周りに余白が作られ、その余白を含めた全体の背景が赤くなります。つまり、大きな赤い四角の中に文字がある状態になります。

「パディング(余白)をつけてから色を塗る」のか、「色を塗ってからパディングをつける」のか。
この順番を意識しないと、「デザイン通りに作ったはずなのに、なんか余白がおかしい…」という沼にハマります。私はこれを勝手に「Modifierの順序ガチャ」と呼んでいて、初心者の頃は適当に入れ替えて試していましたが、理屈がわかれば一発で決まるようになります。

フレーム(Frame)の考え方

もう一つ、.frame() というModifierも重要です。
これはViewのサイズを指定するものですが、SwiftUIでは「親が提案し、子が決定する」という独特なサイズ決定ロジックがあります。

Text("Hello").frame(width: 100, height: 100)
と書くと、テキスト自体が大きくなるのではなく、「100x100の透明な枠の中に、テキストが配置される」という状態になります。
だから、この後に .background(Color.blue) をつけると、100x100の青い四角になりますが、前につけると文字の裏だけが青くなります。

「Viewは常に加工されて新しいViewになる」。この感覚を掴むことが、脱初心者の第一歩です。

レスポンシブ対応の魔術師「Spacer」と「Padding」

スマホアプリ開発で避けて通れないのが、多種多様な画面サイズへの対応です。
iPhone SEのような小さな画面から、iPhone 15 Pro Max、さらにはiPadまで。
ここで役立つのが、Spacer()Padding です。

見えないバネ「Spacer」

Spacer() は、私がSwiftUIで一番好きなコンポーネントです。
これはいわば「空いているスペースを全力で埋め尽くす、透明なバネ」です。

例えば、画面の左端にテキスト、右端にボタンを置きたい時。
CSSなら justify-content: space-between とか書きますよね?
SwiftUIならこうです。

HStack {
    Text("左側")
    Spacer() // ← こいつが中央を押し広げる
    Button("右側") {}
}

このSpacerを入れるだけで、画面幅がどれだけ変わっても、要素は常に両端に配置されます。
VStackに入れれば、上下に押し広げてくれます。
「ここに空白が欲しいな」と思ったら、固定値(frame(height: 50)とか)で指定するのではなく、まずはSpacerで解決できないか考える。これがレスポンシブなレイアウトを作るコツです。

余白を操る「Padding」

.padding() は、引数なしだと「OS標準の適切な余白」を勝手につけてくれます。これが地味に優秀なんです。
Appleのデザインガイドライン(Human Interface Guidelines)に準拠した余白になるので、何も考えずに .padding() をつけるだけで、なんとなく「Appleっぽい」綺麗なレイアウトになります。

もちろん、.padding(.top, 20) のように細かく指定もできますが、最初は標準のpaddingを信じて使うのが、洗練されたUIへの近道です。

複数の異なるサイズのiPhone(SE, Pro, Max)とiPadを並べ、それぞれの画面で同じアプリのUIがSpacerによって完璧にレイアウト調整されている様子を確認してニヤリとしているエンジニアの線画イラスト

リスト表示とグリッド ~データを見せる技術~

アプリ開発の8割は「データのリスト表示」だと言われています。Twitterのタイムラインも、LINEのトーク一覧も、Amazonの商品検索も、全部リストです。
UIKit時代、UITableView を実装するのは本当に大変でした。DataSourceがどうとか、Delegateがどうとか…覚えることが山積みでした。

SwiftUIなら、これです。

List(items) { item in
    Text(item.name)
}

嘘みたいですが、これだけです。
これでスクロールも、セルのリサイクル(メモリ管理)も、タップ時のハイライトも全部やってくれます。

LazyVStackとGridの使い分け

ただし、List はOS標準の見た目(設定画面みたいな感じ)になりがちです。もっと自由にデザインしたい場合は、LazyVStackScrollView を組み合わせます。
「Lazy」がついているのは、「画面に表示される分だけ描画する」という賢い機能を持っているからです。これを忘れて普通の VStack で1000件のデータを表示しようとすると、アプリがフリーズします(これは私も一度やらかしました)。

グリッドレイアウト(Instagramのプロフィール画面の写真一覧のような)も、LazyVGrid を使えば数行で書けます。
カラム数(列数)を固定にするか、画面幅に合わせて自動調整するか(.adaptive)も選べます。iPad対応をするなら、この .adaptive が神機能として働きます。

現場で直面する「SwiftUIの壁」と乗り越え方

ここまで良いことばかり書いてきましたが、現場ならではの苦労がないわけじゃありません。これから副業案件を受ける皆さんがパニックにならないよう、リアルな「壁」と対処法を共有しておきます。

1. 複雑な画面でのパフォーマンス問題

シンプルな画面なら爆速ですが、要素が数百個あるような複雑な画面や、ネスト(入れ子)が深すぎる画面を作ると、スクロールがカクつくことがあります。
対処法: Viewを細かく部品化(Subveiw化)すること。
body の中に全てを書くのではなく、HeaderView, CardView のように別ファイルや別構造体に切り出してください。SwiftUIはViewの更新差分を検知して再描画しますが、細かく分けることでその計算コストを下げられます。あと、単純にコードが読みやすくなります。

2. キーボードが入力欄を隠す問題

これは全モバイルエンジニアの敵です。画面下部のテキストフィールドに入力しようとすると、キーボードがせり上がってきて隠れてしまう現象。
対処法: iOS 14までは自力で頑張る必要がありましたが、今は .ignoresSafeArea(.keyboard) や、サードパーティ製のライブラリ(IQKeyboardManager的なもの)を活用するのが一般的です。案件によっては「iOS 15以上対象」とすることで、SwiftUI標準の機能だけで解決できることも増えてきました。

3. 「UIKitおじさん」との共存

副業案件では、「既存のアプリ(UIKit製)の一部だけをSwiftUIで新しく作りたい」という依頼が結構あります。
ここで「SwiftUIしか知りません」だと、連携部分で詰みます。
対処法: UIHostingController(UIKitの中にSwiftUIを入れる)と UIViewRepresentable(SwiftUIの中にUIKitを入れる)という2つの架け橋の存在を知っておいてください。これを使えば、新旧技術を混ぜて開発できます。私も現場では、地図機能(MapKit)や複雑なテキストエディタだけはUIKitで作り、それをSwiftUIでラップして使うことが多いです。

複数の異なるサイズのiPhone(SE, Pro, Max)とiPadを並べ、それぞれの画面で同じアプリのUIがSpacerによって完璧にレイアウト調整されている様子を確認してニヤリとしているエンジニアの線画イラスト

状態管理(State)を制するものはSwiftUIを制す

レイアウトと同じくらい重要なのが、データの扱い方です。
SwiftUIは「データ(状態)が変われば、勝手に見た目が変わる」という仕組みです。
これを実現するために、@State, @Binding, @ObservedObject, @EnvironmentObject という「プロパティラッパー」を使います。

初心者はここで混乱します。「どれを使えばいいの?」と。
簡単な指針を授けます。

  • @State: その画面内だけで使う、一時的なデータ(トグルのON/OFF、入力中の文字など)。「私物」です。
  • @Binding: 親画面から借りてきたデータ。親子で同期したい時に使います。「借用書」です。
  • @StateObject / @ObservedObject: まとまったデータロジック(ViewModelなど)。外部のクラスを参照する時に使います。
  • @EnvironmentObject: アプリ全体で共有したいデータ(ログイン情報、テーマ設定など)。バケツリレーをせずにデータを渡せます。「放送」です。

最初は @State@Binding の関係性(親から子へデータを渡し、子が変更したら親も変わる)を理解するだけで十分です。これがわかれば、トグルスイッチを作ったり、入力フォームを作ったりできます。

学習ロードマップと案件獲得への道

では、未経験からどうやってSwiftUIを習得し、副業案件獲得まで持っていくか。私がスクールで教えているロードマップを公開します。

ステップ1:Apple公式チュートリアルをやる

Appleの「SwiftUI Tutorials」は非常に完成度が高いです。英語ですが、図や動画が多いのでGoogle翻訳片手に進められます。まずはこれを一周して、「ランドマークアプリ」を完成させてください。

ステップ2:既存アプリの「模写」をする

これが一番力がつきます。iPhoneの設定画面、LINEのトーク一覧、Twitterのプロフィール画面。
これらをSwiftUIで見た目だけそっくりに作ってみてください。
「このレイアウトはどうやればいいんだ?」と悩み、調べる過程で、VStackやSpacerの使い方が身体に染み込みます。

ステップ3:ポートフォリオアプリを作る

模写で自信がついたら、オリジナルのアプリを作ります。
複雑なものである必要はありません。「APIからデータを取ってきてリスト表示する」「タップしたら詳細画面に行く」この基本動作が含まれていればOKです。
重要なのは、App Storeにリリースすること
副業案件の面談で「ストアに公開しているアプリがあります」と言えるだけで、信頼度は爆上がりします。コードが書けるだけでなく、リリースまでの面倒な手続き(証明書周りや審査)を経験しているという証明になるからです。

ステップ4:副業エージェントやクラウドソーシングへ

最初は「SwiftUIでの画面作成のみ」といった切り出し案件や、単価が安めの案件でも良いので実績を作ります。
「UIKitのコードは読めますか?」と聞かれることもあるので、「完全には書けませんが、構造は理解しています」と言えるように、UIKitの基礎(ViewControllerのライフサイクルなど)も少しだけ見ておくと無敵です。

開発中のアプリ画面で、キーボードが出てきても入力欄が隠れないように調整し、さらに複雑なUIを細かくコンポーネント化してコードを整理しているエンジニアの線画イラスト

FAQ:初心者が抱える悩み

Q. Macは必須ですか? iPadじゃダメですか?
A. Macは必須です。 iPadのSwift Playgroundsでもアプリは作れますが、実務レベルの開発や、細かいライブラリ管理、Gitでのバージョン管理を考えるとMac(MacBook Air M1以上推奨)がないと仕事になりません。投資だと思って買ってください。

Q. デザイナーがいなくて、ダサいUIしか作れません…
A. SwiftUIを使えば、標準コンポーネントを並べるだけでそこそこ綺麗になりますが、コツは「余白」「文字サイズ」です。AppleのHuman Interface Guidelinesを一読するだけで、見違えるほどプロっぽくなります。あとは、Figmaなどで上手なデザインをトレースして「なぜ綺麗に見えるのか」を研究しましょう。

Q. 今から始めても遅くないですか?
A. 今がベストタイミングです。 多くの企業がUIKitからSwiftUIへの移行期にあり、SwiftUIを書けるエンジニアを渇望しています。ベテラン勢もSwiftUIに関しては「学習中」の人が多いので、新人でもキャッチアップしやすい土壌があります。

画筆は、もうあなたの手の中にある

ここまで、SwiftUIのレイアウト技術について、かなり深いところまでお話ししてきました。
Stackで積み上げ、Modifierで装飾し、Stateで命を吹き込む。
この感覚を掴んだ時、プログラミングは「作業」から「創作」へと変わります。

私がAuto Layoutの赤い線と格闘していたあの頃、こんな未来が来るとは想像もしていませんでした。
「ここに画像を表示したい」と思ったら Image() と書くだけ。
「角丸にしたい」と思ったら .cornerRadius() と書くだけ。
自分の頭の中にあるイメージが、瞬時に手元のiPhoneの中で動き出す。この全能感こそが、SwiftUIの最大の魅力だと私は思います。

副業やフリーランスとして活動する上で、この「速さ」と「直感性」は強力な武器になります。
クライアントの要望をその場で形にし、「そうそう、これが欲しかったんです!」と言わせる。
その瞬間、あなたは単なるコーダーではなく、価値を提供するパートナーになれるんです。

技術は常に進化します。来年にはまた新しい機能が出るでしょう。
でも、恐れることはありません。SwiftUIの基本思想さえ理解していれば、どんな変化も楽しむことができます。

さあ、Xcodeを開きましょう。
新しいプロジェクトを作成し、プレビュー画面に「Hello World」が表示されたら、そこがあなたの新しいアトリエです。
どんなアプリを描きますか? どんな体験をユーザーに届けますか?
画筆は、もうあなたの手に握られています。

朝日が差し込む窓辺のデスクで、自分のiPhoneで自作アプリがサクサク動いているのを見て、静かな達成感と未来へのワクワクを感じているエンジニアの背中の線画イラスト

あなたが作ったアプリが、世界の誰かの生活を少しだけ便利にしたり、楽しくしたりする日が来ることを、心から楽しみにしています。
まずは小さなViewを一つ、積み上げることから始めてみてください。
Happy Coding!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いたエンジニア

知念 真由のアバター 知念 真由 UI/UXエンジニア

UI/UXの改善を得意とする柔軟な発想力の持ち主。デザインとコードの両方を扱える希少なタイプ。人の気持ちを理解するのが上手く、ユーザー視点での提案が得意。仕事後のジム通いが日課で、体力づくりにも余念がないアクティブな性格。

目次